mirror of
https://github.com/python-telegram-bot/python-telegram-bot.git
synced 2026-06-19 15:45:13 +00:00
Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ccedd3a87d | |||
| 0bb4be55ac | |||
| 21ded420e2 | |||
| 7d893fd04b | |||
| 7015f8dedc | |||
| ac02bce109 | |||
| 3a9a0ab96d | |||
| aba17cb997 | |||
| 038a3b4452 | |||
| b03ebc5a65 | |||
| e9c01c7772 | |||
| 552298595c | |||
| 2a4a0d0ccd | |||
| eb993db473 | |||
| c77ef7eef3 | |||
| a34f0b9bee | |||
| eee8921598 |
+11
-14
@@ -50,6 +50,8 @@ Instructions for making a code change
|
||||
|
||||
The central development branch is ``master``, which should be clean and ready for release at any time. In general, all changes should be done as feature branches based off of ``master``.
|
||||
|
||||
If you want to do solely documentation changes, base them and PR to the branch ``doc-fixes``. This branch also has its own `RTD build`_.
|
||||
|
||||
Here's how to make a one-off code change.
|
||||
|
||||
1. **Choose a descriptive branch name.** It should be lowercase, hyphen-separated, and a noun describing the change (so, ``fuzzy-rules``, but not ``implement-fuzzy-rules``). Also, it shouldn't start with ``hotfix`` or ``release``.
|
||||
@@ -109,12 +111,6 @@ Here's how to make a one-off code change.
|
||||
|
||||
- Before making a commit ensure that all automated tests still pass:
|
||||
|
||||
.. code-block::
|
||||
|
||||
$ make test
|
||||
|
||||
If you don't have ``make``, do:
|
||||
|
||||
.. code-block::
|
||||
|
||||
$ pytest -v
|
||||
@@ -127,18 +123,18 @@ Here's how to make a one-off code change.
|
||||
|
||||
prior to running the tests.
|
||||
|
||||
- To actually make the commit (this will trigger tests for yapf, lint and pep8 automatically):
|
||||
- If you want run style & type checks before committing run
|
||||
|
||||
.. code-block::
|
||||
|
||||
$ pre-commit run -a
|
||||
|
||||
- To actually make the commit (this will trigger tests style & type checks automatically):
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ git add your-file-changed.py
|
||||
|
||||
- yapf may change code formatting, make sure to re-add them to your commit.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ git commit -a -m "your-commit-message-here"
|
||||
|
||||
- Finally, push it to your GitHub fork, run:
|
||||
|
||||
.. code-block:: bash
|
||||
@@ -196,7 +192,7 @@ Style commandments
|
||||
Assert comparison order
|
||||
#######################
|
||||
|
||||
- assert statements should compare in **actual** == **expected** order.
|
||||
Assert statements should compare in **actual** == **expected** order.
|
||||
For example (assuming ``test_call`` is the thing being tested):
|
||||
|
||||
.. code-block:: python
|
||||
@@ -256,3 +252,4 @@ break the API classes. For example:
|
||||
.. _`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
|
||||
.. _`RTD build`: https://python-telegram-bot.readthedocs.io/en/doc-fixes
|
||||
|
||||
@@ -27,4 +27,4 @@ Hey! You're PRing? Cool! Please have a look at the below checklist. It's here to
|
||||
- [ ] 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
|
||||
- [ ] Updated the Bot API version number in all places: `README.rst` and `README_RAW.rst` (including the badge), as well as `telegram.constants.BOT_API_VERSION`
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
name: Warning maintainers
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- requirements.txt
|
||||
- requirements-dev.txt
|
||||
- .pre-commit-config.yaml
|
||||
jobs:
|
||||
job:
|
||||
runs-on: ubuntu-latest
|
||||
name: about pre-commit and dependency change
|
||||
steps:
|
||||
- name: running the check
|
||||
uses: Poolitzer/notifier-action@master
|
||||
with:
|
||||
notify-message: Hey! Looks like you edited the (dev) requirements or the pre-commit hooks. I'm just a friendly reminder to keep the pre-commit hook versions in sync with the dev requirements and the additional dependencies for the hooks in sync with the requirements :)
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
+19
-14
@@ -15,13 +15,6 @@ jobs:
|
||||
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
|
||||
@@ -40,18 +33,30 @@ jobs:
|
||||
python -W ignore -m pip install -r requirements-dev.txt
|
||||
|
||||
- name: Test with pytest
|
||||
# We run 3 different suites here
|
||||
# 1. Test just utils.helpers.py without pytz being installed
|
||||
# 2. Test just test_no_passport.py without passport dependencies being installed
|
||||
# 3. Test everything else
|
||||
# The first & second one are achieved by mocking the corresponding import
|
||||
# See test_helpers.py & test_no_passport.py for details
|
||||
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 ))
|
||||
pytest -v --cov -k test_no_passport.py
|
||||
no_passport_exit=$?
|
||||
export TEST_NO_PASSPORT='false'
|
||||
pytest -v --cov --cov-append -k test_helpers.py
|
||||
no_pytz_exit=$?
|
||||
export TEST_NO_PYTZ='false'
|
||||
pytest -v --cov --cov-append
|
||||
full_exit=$?
|
||||
special_exit=$(( no_pytz_exit > no_passport_exit ? no_pytz_exit : no_passport_exit ))
|
||||
global_exit=$(( special_exit > full_exit ? special_exit : full_exit ))
|
||||
exit ${global_exit}
|
||||
env:
|
||||
JOB_INDEX: ${{ strategy.job-index }}
|
||||
BOTS: W3sidG9rZW4iOiAiNjk2MTg4NzMyOkFBR1Z3RUtmSEhsTmpzY3hFRE5LQXdraEdzdFpfa28xbUMwIiwgInBheW1lbnRfcHJvdmlkZXJfdG9rZW4iOiAiMjg0Njg1MDYzOlRFU1Q6WldGaU1UUmxNbVF5TnpNeSIsICJib3RfbmFtZSI6ICJQVEIgdGVzdHMgb24gVHJhdmlzIHVzaW5nIENQeXRob24gMi43IiwgInN1cGVyX2dyb3VwX2lkIjogIi0xMDAxMzkwOTgzOTk3IiwgImJvdF91c2VybmFtZSI6ICJAcHRiX3RyYXZpc19jcHl0aG9uXzI3X2JvdCJ9LCB7InRva2VuIjogIjY3MTQ2ODg4NjpBQUdQR2ZjaVJJQlVORmU4MjR1SVZkcTdKZTNfWW5BVE5HdyIsICJwYXltZW50X3Byb3ZpZGVyX3Rva2VuIjogIjI4NDY4NTA2MzpURVNUOlpHWXdPVGxrTXpNeE4yWTIiLCAiYm90X25hbWUiOiAiUFRCIHRlc3RzIG9uIFRyYXZpcyB1c2luZyBDUHl0aG9uIDMuNCIsICJzdXBlcl9ncm91cF9pZCI6ICItMTAwMTQ0NjAyMjUyMiIsICJib3RfdXNlcm5hbWUiOiAiQHB0Yl90cmF2aXNfY3B5dGhvbl8zNF9ib3QifSwgeyJ0b2tlbiI6ICI2MjkzMjY1Mzg6QUFGUnJaSnJCN29CM211ekdzR0pYVXZHRTVDUXpNNUNVNG8iLCAicGF5bWVudF9wcm92aWRlcl90b2tlbiI6ICIyODQ2ODUwNjM6VEVTVDpNbU01WVdKaFl6a3hNMlUxIiwgImJvdF9uYW1lIjogIlBUQiB0ZXN0cyBvbiBUcmF2aXMgdXNpbmcgQ1B5dGhvbiAzLjUiLCAic3VwZXJfZ3JvdXBfaWQiOiAiLTEwMDE0OTY5MTc3NTAiLCAiYm90X3VzZXJuYW1lIjogIkBwdGJfdHJhdmlzX2NweXRob25fMzVfYm90In0sIHsidG9rZW4iOiAiNjQwMjA4OTQzOkFBRmhCalFwOXFtM1JUeFN6VXBZekJRakNsZS1Kano1aGNrIiwgInBheW1lbnRfcHJvdmlkZXJfdG9rZW4iOiAiMjg0Njg1MDYzOlRFU1Q6WXpoa1pUZzFOamMxWXpWbCIsICJib3RfbmFtZSI6ICJQVEIgdGVzdHMgb24gVHJhdmlzIHVzaW5nIENQeXRob24gMy42IiwgInN1cGVyX2dyb3VwX2lkIjogIi0xMDAxMzMzODcxNDYxIiwgImJvdF91c2VybmFtZSI6ICJAcHRiX3RyYXZpc19jcHl0aG9uXzM2X2JvdCJ9LCB7InRva2VuIjogIjY5NTEwNDA4ODpBQUhmenlsSU9qU0lJUy1lT25JMjB5MkUyMEhvZEhzZnotMCIsICJwYXltZW50X3Byb3ZpZGVyX3Rva2VuIjogIjI4NDY4NTA2MzpURVNUOk9HUTFNRGd3WmpJd1pqRmwiLCAiYm90X25hbWUiOiAiUFRCIHRlc3RzIG9uIFRyYXZpcyB1c2luZyBDUHl0aG9uIDMuNyIsICJzdXBlcl9ncm91cF9pZCI6ICItMTAwMTQ3ODI5MzcxNCIsICJib3RfdXNlcm5hbWUiOiAiQHB0Yl90cmF2aXNfY3B5dGhvbl8zN19ib3QifSwgeyJ0b2tlbiI6ICI2OTE0MjM1NTQ6QUFGOFdrakNaYm5IcVBfaTZHaFRZaXJGRWxackdhWU9oWDAiLCAicGF5bWVudF9wcm92aWRlcl90b2tlbiI6ICIyODQ2ODUwNjM6VEVTVDpZamM1TlRoaU1tUXlNV1ZoIiwgImJvdF9uYW1lIjogIlBUQiB0ZXN0cyBvbiBUcmF2aXMgdXNpbmcgUHlQeSAyLjciLCAic3VwZXJfZ3JvdXBfaWQiOiAiLTEwMDEzNjM5MzI1NzMiLCAiYm90X3VzZXJuYW1lIjogIkBwdGJfdHJhdmlzX3B5cHlfMjdfYm90In0sIHsidG9rZW4iOiAiNjg0MzM5OTg0OkFBRk1nRUVqcDAxcjVyQjAwN3lDZFZOc2c4QWxOc2FVLWNjIiwgInBheW1lbnRfcHJvdmlkZXJfdG9rZW4iOiAiMjg0Njg1MDYzOlRFU1Q6TVRBek1UWTNNR1V5TmpnMCIsICJib3RfbmFtZSI6ICJQVEIgdGVzdHMgb24gVHJhdmlzIHVzaW5nIFB5UHkgMy41IiwgInN1cGVyX2dyb3VwX2lkIjogIi0xMDAxNDA3ODM2NjA1IiwgImJvdF91c2VybmFtZSI6ICJAcHRiX3RyYXZpc19weXB5XzM1X2JvdCJ9LCB7InRva2VuIjogIjY5MDA5MTM0NzpBQUZMbVI1cEFCNVljcGVfbU9oN3pNNEpGQk9oMHozVDBUbyIsICJwYXltZW50X3Byb3ZpZGVyX3Rva2VuIjogIjI4NDY4NTA2MzpURVNUOlpEaGxOekU1TURrd1lXSmkiLCAiYm90X25hbWUiOiAiUFRCIHRlc3RzIG9uIEFwcFZleW9yIHVzaW5nIENQeXRob24gMy40IiwgInN1cGVyX2dyb3VwX2lkIjogIi0xMDAxMjc5NjAwMDI2IiwgImJvdF91c2VybmFtZSI6ICJAcHRiX2FwcHZleW9yX2NweXRob25fMzRfYm90In0sIHsidG9rZW4iOiAiNjk0MzA4MDUyOkFBRUIyX3NvbkNrNTVMWTlCRzlBTy1IOGp4aVBTNTVvb0JBIiwgInBheW1lbnRfcHJvdmlkZXJfdG9rZW4iOiAiMjg0Njg1MDYzOlRFU1Q6WW1aaVlXWm1NakpoWkdNeSIsICJib3RfbmFtZSI6ICJQVEIgdGVzdHMgb24gQXBwVmV5b3IgdXNpbmcgQ1B5dGhvbiAyLjciLCAic3VwZXJfZ3JvdXBfaWQiOiAiLTEwMDEyOTMwNzkxNjUiLCAiYm90X3VzZXJuYW1lIjogIkBwdGJfYXBwdmV5b3JfY3B5dGhvbl8yN19ib3QifSwgeyJ0b2tlbiI6ICIxMDU1Mzk3NDcxOkFBRzE4bkJfUzJXQXd1SjNnN29oS0JWZ1hYY2VNbklPeVNjIiwgInBheW1lbnRfcHJvdmlkZXJfdG9rZW4iOiAiMjg0Njg1MDYzOlRFU1Q6TmpBd056QXpZalZpTkdOayIsICJuYW1lIjogIlBUQiB0ZXN0cyBbMF0iLCAic3VwZXJfZ3JvdXBfaWQiOiAiLTEwMDExODU1MDk2MzYiLCAidXNlcm5hbWUiOiAicHRiXzBfYm90In0sIHsidG9rZW4iOiAiMTA0NzMyNjc3MTpBQUY4bk90ODFGcFg4bGJidno4VWV3UVF2UmZUYkZmQnZ1SSIsICJwYXltZW50X3Byb3ZpZGVyX3Rva2VuIjogIjI4NDY4NTA2MzpURVNUOllUVTFOVEk0WkdSallqbGkiLCAibmFtZSI6ICJQVEIgdGVzdHMgWzFdIiwgInN1cGVyX2dyb3VwX2lkIjogIi0xMDAxNDg0Nzk3NjEyIiwgInVzZXJuYW1lIjogInB0Yl8xX2JvdCJ9LCB7InRva2VuIjogIjk3MTk5Mjc0NTpBQUdPa09hVzBOSGpnSXY1LTlqUWJPajR2R3FkaFNGLVV1cyIsICJwYXltZW50X3Byb3ZpZGVyX3Rva2VuIjogIjI4NDY4NTA2MzpURVNUOk5XWmtNV1ZoWWpsallqVTUiLCAibmFtZSI6ICJQVEIgdGVzdHMgWzJdIiwgInN1cGVyX2dyb3VwX2lkIjogIi0xMDAxNDAyMjU1MDcwIiwgInVzZXJuYW1lIjogInB0Yl8yX2JvdCJ9XQ==
|
||||
TEST_BUILD: ${{ matrix.test-build }}
|
||||
TEST_PRE_COMMIT: ${{ matrix.test-pre-commit }}
|
||||
TEST_NO_PYTZ : "true"
|
||||
TEST_NO_PASSPORT: "true"
|
||||
TEST_BUILD: "true"
|
||||
shell: bash --noprofile --norc {0}
|
||||
|
||||
- name: Submit coverage
|
||||
|
||||
+29
-7
@@ -1,6 +1,6 @@
|
||||
# Make sure that
|
||||
# * the revs specified here match requirements-dev.txt
|
||||
# * the makefile checks the same files as pre-commit
|
||||
# * the additional_dependencies here match requirements.txt
|
||||
repos:
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 20.8b1
|
||||
@@ -14,21 +14,43 @@ repos:
|
||||
hooks:
|
||||
- id: flake8
|
||||
- repo: https://github.com/PyCQA/pylint
|
||||
rev: pylint-2.6.0
|
||||
rev: pylint-2.7.2
|
||||
hooks:
|
||||
- id: pylint
|
||||
files: ^(telegram|examples)/.*\.py$
|
||||
args:
|
||||
- --rcfile=setup.cfg
|
||||
- --rcfile=setup.cfg
|
||||
additional_dependencies:
|
||||
- certifi
|
||||
- tornado>=5.1
|
||||
- APScheduler==3.6.3
|
||||
- . # this basically does `pip install -e .`
|
||||
- repo: https://github.com/pre-commit/mirrors-mypy
|
||||
rev: v0.790
|
||||
rev: v0.812
|
||||
hooks:
|
||||
- id: mypy
|
||||
files: ^(telegram|examples)/.*\.py$
|
||||
name: mypy-ptb
|
||||
files: ^telegram/.*\.py$
|
||||
additional_dependencies:
|
||||
- certifi
|
||||
- tornado>=5.1
|
||||
- APScheduler==3.6.3
|
||||
- . # this basically does `pip install -e .`
|
||||
- id: mypy
|
||||
name: mypy-examples
|
||||
files: ^examples/.*\.py$
|
||||
args:
|
||||
- --no-strict-optional
|
||||
- --follow-imports=silent
|
||||
additional_dependencies:
|
||||
- certifi
|
||||
- tornado>=5.1
|
||||
- APScheduler==3.6.3
|
||||
- . # this basically does `pip install -e .`
|
||||
- repo: https://github.com/asottile/pyupgrade
|
||||
rev: v2.7.4
|
||||
rev: v2.10.0
|
||||
hooks:
|
||||
- id: pyupgrade
|
||||
files: ^(telegram|examples|tests)/.*\.py$
|
||||
args:
|
||||
- --py36-plus
|
||||
- --py36-plus
|
||||
|
||||
+17
-5
@@ -1,10 +1,22 @@
|
||||
# syntax: https://docs.readthedocs.io/en/latest/yaml-config.html
|
||||
# .readthedocs.yaml
|
||||
# Read the Docs configuration file
|
||||
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
|
||||
|
||||
# Required
|
||||
version: 2
|
||||
|
||||
# Build documentation in the docs/ directory with Sphinx
|
||||
sphinx:
|
||||
configuration: docs/source/conf.py
|
||||
|
||||
# Optionally build your docs in additional formats such as PDF
|
||||
formats:
|
||||
- pdf
|
||||
- pdf
|
||||
|
||||
# Optionally set the version of Python and requirements required to build your docs
|
||||
python:
|
||||
setup_py_install: true
|
||||
version: 3
|
||||
|
||||
requirements_file: docs/requirements-docs.txt
|
||||
install:
|
||||
- method: pip
|
||||
path: .
|
||||
- requirements: docs/requirements-docs.txt
|
||||
|
||||
+10
-2
@@ -2,12 +2,20 @@ Credits
|
||||
=======
|
||||
|
||||
``python-telegram-bot`` was originally created by
|
||||
`Leandro Toledo <https://github.com/leandrotoledo>`_ and is now maintained by `Hinrich Mahler <https://github.com/Bibo-Joshi>`_.
|
||||
`Leandro Toledo <https://github.com/leandrotoledo>`_.
|
||||
The current development team includes
|
||||
|
||||
- `Hinrich Mahler <https://github.com/Bibo-Joshi>`_ (maintainer)
|
||||
- `Poolitzer <https://github.com/Poolitzer>`_ (community liaison)
|
||||
- `Shivam <https://github.com/Starry69>`_
|
||||
- `Harshil <https://github.com/harshil21>`_
|
||||
|
||||
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.
|
||||
Vendored packages
|
||||
-----------------
|
||||
|
||||
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:
|
||||
|
||||
+60
@@ -2,6 +2,66 @@
|
||||
Changelog
|
||||
=========
|
||||
|
||||
Version 13.4.1
|
||||
==============
|
||||
*Released 2021-03-14*
|
||||
|
||||
**Hot fix release:**
|
||||
|
||||
- Fixed a bug in ``setup.py`` (`#2431`_)
|
||||
|
||||
.. _`#2431`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2431
|
||||
|
||||
Version 13.4
|
||||
============
|
||||
*Released 2021-03-14*
|
||||
|
||||
**Major Changes:**
|
||||
|
||||
- Full support of Bot API 5.1 (`#2424`_)
|
||||
|
||||
**Minor changes, CI improvements, doc fixes and type hinting:**
|
||||
|
||||
- Improve ``Updater.set_webhook`` (`#2419`_)
|
||||
- Doc Fixes (`#2404`_)
|
||||
- Type Hinting Fixes (`#2425`_)
|
||||
- Update ``pre-commit`` Settings (`#2415`_)
|
||||
- Fix Logging for Vendored ``urllib3`` (`#2427`_)
|
||||
- Stabilize Tests (`#2409`_)
|
||||
|
||||
.. _`#2424`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2424
|
||||
.. _`#2419`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2419
|
||||
.. _`#2404`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2404
|
||||
.. _`#2425`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2425
|
||||
.. _`#2415`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2415
|
||||
.. _`#2427`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2427
|
||||
.. _`#2409`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2409
|
||||
|
||||
Version 13.3
|
||||
============
|
||||
*Released 2021-02-19*
|
||||
|
||||
**Major Changes:**
|
||||
|
||||
- Make ``cryptography`` Dependency Optional & Refactor Some Tests (`#2386`_, `#2370`_)
|
||||
- Deprecate ``MessageQueue`` (`#2393`_)
|
||||
|
||||
**Bug Fixes:**
|
||||
|
||||
- Refactor ``Defaults`` Integration (`#2363`_)
|
||||
- Add Missing ``telegram.SecureValue`` to init and Docs (`#2398`_)
|
||||
|
||||
**Minor changes:**
|
||||
|
||||
- Doc Fixes (`#2359`_)
|
||||
|
||||
.. _`#2386`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2386
|
||||
.. _`#2370`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2370
|
||||
.. _`#2393`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2393
|
||||
.. _`#2363`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2363
|
||||
.. _`#2398`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2398
|
||||
.. _`#2359`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2359
|
||||
|
||||
Version 13.2
|
||||
============
|
||||
*Released 2021-02-02*
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
.DEFAULT_GOAL := help
|
||||
.PHONY: clean pep8 black lint test install
|
||||
|
||||
PYLINT := pylint
|
||||
PYTEST := pytest
|
||||
PEP8 := flake8
|
||||
BLACK := black
|
||||
MYPY := mypy
|
||||
PIP := pip
|
||||
|
||||
clean:
|
||||
rm -fr build
|
||||
rm -fr dist
|
||||
find . -name '*.pyc' -exec rm -f {} \;
|
||||
find . -name '*.pyo' -exec rm -f {} \;
|
||||
find . -name '*~' -exec rm -f {} \;
|
||||
find . -regex "./telegram[0-9]*.\(jpg\|mp3\|mp4\|ogg\|png\|webp\)" -exec rm {} \;
|
||||
|
||||
pep8:
|
||||
$(PEP8) telegram tests examples
|
||||
|
||||
black:
|
||||
$(BLACK) .
|
||||
|
||||
lint:
|
||||
$(PYLINT) --rcfile=setup.cfg telegram examples
|
||||
|
||||
mypy:
|
||||
$(MYPY) -p telegram
|
||||
$(MYPY) examples
|
||||
|
||||
test:
|
||||
$(PYTEST) -v
|
||||
|
||||
install:
|
||||
$(PIP) install -r requirements.txt -r requirements-dev.txt
|
||||
|
||||
help:
|
||||
@echo "Available targets:"
|
||||
@echo "- clean Clean up the source directory"
|
||||
@echo "- pep8 Check style with flake8"
|
||||
@echo "- lint Check style with pylint"
|
||||
@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 "- PEP8 default: $(PEP8)"
|
||||
@echo "- BLACK default: $(BLACK)"
|
||||
@echo "- MYPY default: $(MYPY)"
|
||||
@echo "- PIP default: $(PIP)"
|
||||
+17
-2
@@ -20,7 +20,7 @@ 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://img.shields.io/badge/Bot%20API-5.0-blue?logo=telegram
|
||||
.. image:: https://img.shields.io/badge/Bot%20API-5.1-blue?logo=telegram
|
||||
:target: https://core.telegram.org/bots/api-changelog
|
||||
:alt: Supported Bot API versions
|
||||
|
||||
@@ -111,7 +111,7 @@ Installing both ``python-telegram-bot`` and ``python-telegram-bot-raw`` in conju
|
||||
Telegram API support
|
||||
====================
|
||||
|
||||
All types and methods of the Telegram Bot API **5.0** are supported.
|
||||
All types and methods of the Telegram Bot API **5.1** are supported.
|
||||
|
||||
==========
|
||||
Installing
|
||||
@@ -137,6 +137,16 @@ In case you have a previously cloned local repository already, you should initia
|
||||
|
||||
$ git submodule update --init --recursive
|
||||
|
||||
---------------------
|
||||
Optional Dependencies
|
||||
---------------------
|
||||
|
||||
PTB can be installed with optional dependencies:
|
||||
|
||||
* ``pip install python-telegram-bot[passport]`` installs the `cryptography <https://cryptography.io>`_ library. Use this, if you want to use Telegram Passport related functionality.
|
||||
* ``pip install python-telegram-bot[ujson]`` installs the `ujson <https://pypi.org/project/ujson/>`_ library. It will then be used for JSON de- & encoding, which can bring speed up compared to the standard `json <https://docs.python.org/3/library/json.html>`_ library.
|
||||
* ``pip install python-telegram-bot[socks]`` installs the `PySocks <https://pypi.org/project/PySocks/>`_ library. Use this, if you want to work behind a Socks5 server.
|
||||
|
||||
===============
|
||||
Getting started
|
||||
===============
|
||||
@@ -220,6 +230,11 @@ 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>`_.
|
||||
|
||||
========
|
||||
Donating
|
||||
========
|
||||
Occasionally we are asked if we accept donations to support the development. While we appreciate the thought, maintaining PTB is our hobby and we have almost no running costs for it. We therefore have nothing set up to accept donations. If you still want to donate, we kindly ask you to donate to another open source project/initiative of your choice instead.
|
||||
|
||||
=======
|
||||
License
|
||||
=======
|
||||
|
||||
+20
-6
@@ -13,22 +13,22 @@ We have a vibrant community of developers helping each other in our `Telegram gr
|
||||
*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/
|
||||
:target: https://pypi.org/project/python-telegram-bot-raw/
|
||||
:alt: PyPi Package Version
|
||||
|
||||
.. image:: https://img.shields.io/pypi/pyversions/python-telegram-bot-raw.svg
|
||||
:target: https://pypi.org/project/python-telegram-bot/
|
||||
:target: https://pypi.org/project/python-telegram-bot-raw/
|
||||
:alt: Supported Python versions
|
||||
|
||||
.. image:: https://img.shields.io/badge/Bot%20API-5.0-blue?logo=telegram
|
||||
.. image:: https://img.shields.io/badge/Bot%20API-5.1-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
|
||||
:target: https://pypistats.org/packages/python-telegram-bot-raw
|
||||
:alt: PyPi Package Monthly Download
|
||||
|
||||
.. image:: https://img.shields.io/badge/docs-latest-af1a97.svg
|
||||
.. image:: https://readthedocs.org/projects/python-telegram-bot/badge/?version=stable
|
||||
:target: https://python-telegram-bot.readthedocs.io/
|
||||
:alt: Documentation Status
|
||||
|
||||
@@ -105,7 +105,7 @@ Installing both ``python-telegram-bot`` and ``python-telegram-bot-raw`` in conju
|
||||
Telegram API support
|
||||
====================
|
||||
|
||||
All types and methods of the Telegram Bot API **5.0** are supported.
|
||||
All types and methods of the Telegram Bot API **5.1** are supported.
|
||||
|
||||
==========
|
||||
Installing
|
||||
@@ -137,6 +137,15 @@ 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`.
|
||||
|
||||
---------------------
|
||||
Optional Dependencies
|
||||
---------------------
|
||||
|
||||
PTB can be installed with optional dependencies:
|
||||
|
||||
* ``pip install python-telegram-bot-raw[passport]`` installs the `cryptography <https://cryptography.io>`_ library. Use this, if you want to use Telegram Passport related functionality.
|
||||
* ``pip install python-telegram-bot-raw[ujson]`` installs the `ujson <https://pypi.org/project/ujson/>`_ library. It will then be used for JSON de- & encoding, which can bring speed up compared to the standard `json <https://docs.python.org/3/library/json.html>`_ library.
|
||||
|
||||
===============
|
||||
Getting started
|
||||
===============
|
||||
@@ -203,6 +212,11 @@ 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>`_.
|
||||
|
||||
========
|
||||
Donating
|
||||
========
|
||||
Occasionally we are asked if we accept donations to support the development. While we appreciate the thought, maintaining PTB is our hobby and we have almost no running costs for it. We therefore have nothing set up to accept donations. If you still want to donate, we kindly ask you to donate to another open source project/initiative of your choice instead.
|
||||
|
||||
=======
|
||||
License
|
||||
=======
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
sphinx>=1.7.9
|
||||
sphinx_rtd_theme
|
||||
sphinx==3.5.2
|
||||
sphinx_rtd_theme==0.5.1
|
||||
sphinx-pypi-upload
|
||||
|
||||
+6
-3
@@ -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.7.9'
|
||||
needs_sphinx = '3.5.2'
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
@@ -33,6 +33,9 @@ extensions = [
|
||||
'sphinx.ext.autodoc',
|
||||
'sphinx.ext.napoleon'
|
||||
]
|
||||
# Don't show type hints in the signature - that just makes it hardly readable
|
||||
# and we document the types anyway
|
||||
autodoc_typehints = 'none'
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
@@ -58,9 +61,9 @@ author = u'Leandro Toledo'
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '13.2' # telegram.__version__[:3]
|
||||
version = '13.4.1' # telegram.__version__[:3]
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '13.2' # telegram.__version__
|
||||
release = '13.4.1' # telegram.__version__
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
telegram.ChatInviteLink
|
||||
=======================
|
||||
|
||||
.. autoclass:: telegram.ChatInviteLink
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,6 @@
|
||||
telegram.ChatMemberUpdated
|
||||
==========================
|
||||
|
||||
.. autoclass:: telegram.ChatMemberUpdated
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,6 @@
|
||||
telegram.ext.ChatMemberHandler
|
||||
==============================
|
||||
|
||||
.. autoclass:: telegram.ext.ChatMemberHandler
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -21,6 +21,7 @@ Handlers
|
||||
telegram.ext.handler
|
||||
telegram.ext.callbackqueryhandler
|
||||
telegram.ext.choseninlineresulthandler
|
||||
telegram.ext.chatmemberhandler
|
||||
telegram.ext.commandhandler
|
||||
telegram.ext.conversationhandler
|
||||
telegram.ext.inlinequeryhandler
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
telegram.MessageAutoDeleteTimerChanged
|
||||
======================================
|
||||
|
||||
.. autoclass:: telegram.MessageAutoDeleteTimerChanged
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -13,8 +13,10 @@ telegram package
|
||||
telegram.callbackquery
|
||||
telegram.chat
|
||||
telegram.chataction
|
||||
telegram.chatinvitelink
|
||||
telegram.chatlocation
|
||||
telegram.chatmember
|
||||
telegram.chatmemberupdated
|
||||
telegram.chatpermissions
|
||||
telegram.chatphoto
|
||||
telegram.constants
|
||||
@@ -38,6 +40,7 @@ telegram package
|
||||
telegram.location
|
||||
telegram.loginurl
|
||||
telegram.message
|
||||
telegram.messageautodeletetimerchanged
|
||||
telegram.messageid
|
||||
telegram.messageentity
|
||||
telegram.parsemode
|
||||
@@ -57,6 +60,9 @@ telegram package
|
||||
telegram.video
|
||||
telegram.videonote
|
||||
telegram.voice
|
||||
telegram.voicechatstarted
|
||||
telegram.voicechatended
|
||||
telegram.voicechatparticipantsinvited
|
||||
telegram.webhookinfo
|
||||
|
||||
Stickers
|
||||
@@ -140,6 +146,7 @@ Passport
|
||||
telegram.credentials
|
||||
telegram.datacredentials
|
||||
telegram.securedata
|
||||
telegram.securevalue
|
||||
telegram.filecredentials
|
||||
telegram.iddocumentdata
|
||||
telegram.personaldetails
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
telegram.SecureValue
|
||||
====================
|
||||
|
||||
.. autoclass:: telegram.SecureValue
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,7 @@
|
||||
telegram.VoiceChatEnded
|
||||
=======================
|
||||
|
||||
.. autoclass:: telegram.VoiceChatEnded
|
||||
:members:
|
||||
:show-inheritance:
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
telegram.VoiceChatParticipantsInvited
|
||||
=====================================
|
||||
|
||||
.. autoclass:: telegram.VoiceChatParticipantsInvited
|
||||
:members:
|
||||
:show-inheritance:
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
telegram.VoiceChatStarted
|
||||
=========================
|
||||
|
||||
.. autoclass:: telegram.VoiceChatStarted
|
||||
:members:
|
||||
:show-inheritance:
|
||||
|
||||
+13
-14
@@ -1,6 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=W0613, C0116
|
||||
# type: ignore[union-attr]
|
||||
# pylint: disable=C0116
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""
|
||||
@@ -37,7 +36,7 @@ logger = logging.getLogger(__name__)
|
||||
GENDER, PHOTO, LOCATION, BIO = range(4)
|
||||
|
||||
|
||||
def start(update: Update, context: CallbackContext) -> int:
|
||||
def start(update: Update, _: CallbackContext) -> int:
|
||||
reply_keyboard = [['Boy', 'Girl', 'Other']]
|
||||
|
||||
update.message.reply_text(
|
||||
@@ -50,7 +49,7 @@ def start(update: Update, context: CallbackContext) -> int:
|
||||
return GENDER
|
||||
|
||||
|
||||
def gender(update: Update, context: CallbackContext) -> int:
|
||||
def gender(update: Update, _: CallbackContext) -> int:
|
||||
user = update.message.from_user
|
||||
logger.info("Gender of %s: %s", user.first_name, update.message.text)
|
||||
update.message.reply_text(
|
||||
@@ -62,52 +61,52 @@ def gender(update: Update, context: CallbackContext) -> int:
|
||||
return PHOTO
|
||||
|
||||
|
||||
def photo(update: Update, context: CallbackContext) -> int:
|
||||
def photo(update: Update, _: CallbackContext) -> int:
|
||||
user = update.message.from_user
|
||||
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.'
|
||||
'Gorgeous! Now, send me your location please, or send /skip if you don\'t want to.'
|
||||
)
|
||||
|
||||
return LOCATION
|
||||
|
||||
|
||||
def skip_photo(update: Update, context: CallbackContext) -> int:
|
||||
def skip_photo(update: Update, _: 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.'
|
||||
'I bet you look great! Now, send me your location please, or send /skip.'
|
||||
)
|
||||
|
||||
return LOCATION
|
||||
|
||||
|
||||
def location(update: Update, context: CallbackContext) -> int:
|
||||
def location(update: Update, _: 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.'
|
||||
'Maybe I can visit you sometime! At last, tell me something about yourself.'
|
||||
)
|
||||
|
||||
return BIO
|
||||
|
||||
|
||||
def skip_location(update: Update, context: CallbackContext) -> int:
|
||||
def skip_location(update: Update, _: 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.'
|
||||
'You seem a bit paranoid! At last, tell me something about yourself.'
|
||||
)
|
||||
|
||||
return BIO
|
||||
|
||||
|
||||
def bio(update: Update, context: CallbackContext) -> int:
|
||||
def bio(update: Update, _: 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.')
|
||||
@@ -115,7 +114,7 @@ def bio(update: Update, context: CallbackContext) -> int:
|
||||
return ConversationHandler.END
|
||||
|
||||
|
||||
def cancel(update: Update, context: CallbackContext) -> int:
|
||||
def cancel(update: Update, _: CallbackContext) -> int:
|
||||
user = update.message.from_user
|
||||
logger.info("User %s canceled the conversation.", user.first_name)
|
||||
update.message.reply_text(
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=W0613, C0116
|
||||
# type: ignore[union-attr]
|
||||
# pylint: disable=C0116
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""
|
||||
@@ -54,7 +53,7 @@ def facts_to_str(user_data: Dict[str, str]) -> str:
|
||||
return "\n".join(facts).join(['\n', '\n'])
|
||||
|
||||
|
||||
def start(update: Update, context: CallbackContext) -> int:
|
||||
def start(update: Update, _: 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?",
|
||||
@@ -72,9 +71,9 @@ def regular_choice(update: Update, context: CallbackContext) -> int:
|
||||
return TYPING_REPLY
|
||||
|
||||
|
||||
def custom_choice(update: Update, context: CallbackContext) -> int:
|
||||
def custom_choice(update: Update, _: CallbackContext) -> int:
|
||||
update.message.reply_text(
|
||||
'Alright, please send me the category first, ' 'for example "Most impressive skill"'
|
||||
'Alright, please send me the category first, for example "Most impressive skill"'
|
||||
)
|
||||
|
||||
return TYPING_CHOICE
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=W0613, C0116
|
||||
# type: ignore[union-attr]
|
||||
# pylint: disable=C0116
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""Bot that explains Telegram's "Deep Linking Parameters" functionality.
|
||||
@@ -79,7 +78,7 @@ def deep_linked_level_2(update: Update, context: CallbackContext) -> None:
|
||||
update.message.reply_text(text, parse_mode=ParseMode.MARKDOWN, disable_web_page_preview=True)
|
||||
|
||||
|
||||
def deep_linked_level_3(update: Update, context: CallbackContext) -> None:
|
||||
def deep_linked_level_3(update: Update, _: CallbackContext) -> None:
|
||||
"""Reached through the USING_ENTITIES payload"""
|
||||
update.message.reply_text(
|
||||
"It is also possible to make deep-linking using InlineKeyboardButtons.",
|
||||
@@ -104,7 +103,7 @@ def deep_linked_level_4(update: Update, context: CallbackContext) -> None:
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
def main() -> None:
|
||||
"""Start the bot."""
|
||||
# Create the Updater and pass it your bot's token.
|
||||
updater = Updater("TOKEN")
|
||||
|
||||
+5
-6
@@ -1,6 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=W0613, C0116
|
||||
# type: ignore[union-attr]
|
||||
# pylint: disable=C0116
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""
|
||||
@@ -31,22 +30,22 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
# 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:
|
||||
def start(update: Update, _: CallbackContext) -> None:
|
||||
"""Send a message when the command /start is issued."""
|
||||
update.message.reply_text('Hi!')
|
||||
|
||||
|
||||
def help_command(update: Update, context: CallbackContext) -> None:
|
||||
def help_command(update: Update, _: CallbackContext) -> None:
|
||||
"""Send a message when the command /help is issued."""
|
||||
update.message.reply_text('Help!')
|
||||
|
||||
|
||||
def echo(update: Update, context: CallbackContext) -> None:
|
||||
def echo(update: Update, _: CallbackContext) -> None:
|
||||
"""Echo the user message."""
|
||||
update.message.reply_text(update.message.text)
|
||||
|
||||
|
||||
def main():
|
||||
def main() -> None:
|
||||
"""Start the bot."""
|
||||
# Create the Updater and pass it your bot's token.
|
||||
updater = Updater("TOKEN")
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=W0613, C0116
|
||||
# type: ignore[union-attr]
|
||||
# pylint: disable=C0116
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""
|
||||
@@ -28,7 +27,7 @@ BOT_TOKEN = "TOKEN"
|
||||
DEVELOPER_CHAT_ID = 123456789
|
||||
|
||||
|
||||
def error_handler(update: Update, context: CallbackContext) -> None:
|
||||
def error_handler(update: object, 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)
|
||||
@@ -40,9 +39,10 @@ def error_handler(update: Update, context: CallbackContext) -> None:
|
||||
|
||||
# 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.
|
||||
update_str = update.to_dict() if isinstance(update, Update) else str(update)
|
||||
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))}'
|
||||
f'<pre>update = {html.escape(json.dumps(update_str, 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'
|
||||
@@ -53,19 +53,19 @@ def error_handler(update: Update, context: CallbackContext) -> None:
|
||||
context.bot.send_message(chat_id=DEVELOPER_CHAT_ID, text=message, parse_mode=ParseMode.HTML)
|
||||
|
||||
|
||||
def bad_command(update: Update, context: CallbackContext) -> None:
|
||||
def bad_command(_: Update, context: CallbackContext) -> None:
|
||||
"""Raise an error to trigger the error handler."""
|
||||
context.bot.wrong_method_name()
|
||||
context.bot.wrong_method_name() # type: ignore[attr-defined]
|
||||
|
||||
|
||||
def start(update: Update, context: CallbackContext) -> None:
|
||||
def start(update: Update, _: 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():
|
||||
def main() -> None:
|
||||
# Create the Updater and pass it your bot's token.
|
||||
updater = Updater(BOT_TOKEN)
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=W0613, C0116
|
||||
# type: ignore[union-attr]
|
||||
# pylint: disable=C0116
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""
|
||||
@@ -30,32 +29,34 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
# 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:
|
||||
def start(update: Update, _: CallbackContext) -> None:
|
||||
"""Send a message when the command /start is issued."""
|
||||
update.message.reply_text('Hi!')
|
||||
|
||||
|
||||
def help_command(update: Update, context: CallbackContext) -> None:
|
||||
def help_command(update: Update, _: CallbackContext) -> None:
|
||||
"""Send a message when the command /help is issued."""
|
||||
update.message.reply_text('Help!')
|
||||
|
||||
|
||||
def inlinequery(update: Update, context: CallbackContext) -> None:
|
||||
def inlinequery(update: Update, _: CallbackContext) -> None:
|
||||
"""Handle the inline query."""
|
||||
query = update.inline_query.query
|
||||
results = [
|
||||
InlineQueryResultArticle(
|
||||
id=uuid4(), title="Caps", input_message_content=InputTextMessageContent(query.upper())
|
||||
id=str(uuid4()),
|
||||
title="Caps",
|
||||
input_message_content=InputTextMessageContent(query.upper()),
|
||||
),
|
||||
InlineQueryResultArticle(
|
||||
id=uuid4(),
|
||||
id=str(uuid4()),
|
||||
title="Bold",
|
||||
input_message_content=InputTextMessageContent(
|
||||
f"*{escape_markdown(query)}*", parse_mode=ParseMode.MARKDOWN
|
||||
),
|
||||
),
|
||||
InlineQueryResultArticle(
|
||||
id=uuid4(),
|
||||
id=str(uuid4()),
|
||||
title="Italic",
|
||||
input_message_content=InputTextMessageContent(
|
||||
f"_{escape_markdown(query)}_", parse_mode=ParseMode.MARKDOWN
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=W0613, C0116
|
||||
# type: ignore[union-attr]
|
||||
# pylint: disable=C0116
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""
|
||||
@@ -17,7 +16,7 @@ logging.basicConfig(
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def start(update: Update, context: CallbackContext) -> None:
|
||||
def start(update: Update, _: CallbackContext) -> None:
|
||||
keyboard = [
|
||||
[
|
||||
InlineKeyboardButton("Option 1", callback_data='1'),
|
||||
@@ -31,7 +30,7 @@ def start(update: Update, context: CallbackContext) -> None:
|
||||
update.message.reply_text('Please choose:', reply_markup=reply_markup)
|
||||
|
||||
|
||||
def button(update: Update, context: CallbackContext) -> None:
|
||||
def button(update: Update, _: CallbackContext) -> None:
|
||||
query = update.callback_query
|
||||
|
||||
# CallbackQueries need to be answered, even if no notification to the user is needed
|
||||
@@ -41,11 +40,11 @@ def button(update: Update, context: CallbackContext) -> None:
|
||||
query.edit_message_text(text=f"Selected option: {query.data}")
|
||||
|
||||
|
||||
def help_command(update: Update, context: CallbackContext) -> None:
|
||||
def help_command(update: Update, _: CallbackContext) -> None:
|
||||
update.message.reply_text("Use /start to test this bot.")
|
||||
|
||||
|
||||
def main():
|
||||
def main() -> None:
|
||||
# Create the Updater and pass it your bot's token.
|
||||
updater = Updater("TOKEN")
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=W0613, C0116
|
||||
# type: ignore[union-attr]
|
||||
# pylint: disable=C0116
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""Simple inline keyboard bot with multiple CallbackQueryHandlers.
|
||||
@@ -38,7 +37,7 @@ FIRST, SECOND = range(2)
|
||||
ONE, TWO, THREE, FOUR = range(4)
|
||||
|
||||
|
||||
def start(update: Update, context: CallbackContext) -> None:
|
||||
def start(update: Update, _: CallbackContext) -> int:
|
||||
"""Send message on `/start`."""
|
||||
# Get user that sent /start and log his name
|
||||
user = update.message.from_user
|
||||
@@ -60,7 +59,7 @@ def start(update: Update, context: CallbackContext) -> None:
|
||||
return FIRST
|
||||
|
||||
|
||||
def start_over(update: Update, context: CallbackContext) -> None:
|
||||
def start_over(update: Update, _: CallbackContext) -> int:
|
||||
"""Prompt same text & keyboard as `start` does but not as new message"""
|
||||
# Get CallbackQuery from Update
|
||||
query = update.callback_query
|
||||
@@ -81,7 +80,7 @@ def start_over(update: Update, context: CallbackContext) -> None:
|
||||
return FIRST
|
||||
|
||||
|
||||
def one(update: Update, context: CallbackContext) -> None:
|
||||
def one(update: Update, _: CallbackContext) -> int:
|
||||
"""Show new choice of buttons"""
|
||||
query = update.callback_query
|
||||
query.answer()
|
||||
@@ -98,7 +97,7 @@ def one(update: Update, context: CallbackContext) -> None:
|
||||
return FIRST
|
||||
|
||||
|
||||
def two(update: Update, context: CallbackContext) -> None:
|
||||
def two(update: Update, _: CallbackContext) -> int:
|
||||
"""Show new choice of buttons"""
|
||||
query = update.callback_query
|
||||
query.answer()
|
||||
@@ -115,7 +114,7 @@ def two(update: Update, context: CallbackContext) -> None:
|
||||
return FIRST
|
||||
|
||||
|
||||
def three(update: Update, context: CallbackContext) -> None:
|
||||
def three(update: Update, _: CallbackContext) -> int:
|
||||
"""Show new choice of buttons"""
|
||||
query = update.callback_query
|
||||
query.answer()
|
||||
@@ -133,7 +132,7 @@ def three(update: Update, context: CallbackContext) -> None:
|
||||
return SECOND
|
||||
|
||||
|
||||
def four(update: Update, context: CallbackContext) -> None:
|
||||
def four(update: Update, _: CallbackContext) -> int:
|
||||
"""Show new choice of buttons"""
|
||||
query = update.callback_query
|
||||
query.answer()
|
||||
@@ -150,7 +149,7 @@ def four(update: Update, context: CallbackContext) -> None:
|
||||
return FIRST
|
||||
|
||||
|
||||
def end(update: Update, context: CallbackContext) -> None:
|
||||
def end(update: Update, _: CallbackContext) -> int:
|
||||
"""Returns `ConversationHandler.END`, which tells the
|
||||
ConversationHandler that the conversation is over"""
|
||||
query = update.callback_query
|
||||
@@ -159,7 +158,7 @@ def end(update: Update, context: CallbackContext) -> None:
|
||||
return ConversationHandler.END
|
||||
|
||||
|
||||
def main():
|
||||
def main() -> None:
|
||||
# Create the Updater and pass it your bot's token.
|
||||
updater = Updater("TOKEN")
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=W0613, C0116
|
||||
# type: ignore[union-attr]
|
||||
# pylint: disable=C0116
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""
|
||||
@@ -16,6 +15,7 @@ bot.
|
||||
"""
|
||||
|
||||
import logging
|
||||
from typing import Tuple, Dict, Any
|
||||
|
||||
from telegram import InlineKeyboardMarkup, InlineKeyboardButton, Update
|
||||
from telegram.ext import (
|
||||
@@ -64,14 +64,14 @@ END = ConversationHandler.END
|
||||
|
||||
|
||||
# Helper
|
||||
def _name_switcher(level):
|
||||
def _name_switcher(level: str) -> Tuple[str, str]:
|
||||
if level == PARENTS:
|
||||
return 'Father', 'Mother'
|
||||
return 'Brother', 'Sister'
|
||||
|
||||
|
||||
# Top level conversation callbacks
|
||||
def start(update: Update, context: CallbackContext) -> None:
|
||||
def start(update: Update, context: CallbackContext) -> str:
|
||||
"""Select an action: Adding parent/child or show data."""
|
||||
text = (
|
||||
'You may add a familiy member, yourself show the gathered data or end the '
|
||||
@@ -103,7 +103,7 @@ def start(update: Update, context: CallbackContext) -> None:
|
||||
return SELECTING_ACTION
|
||||
|
||||
|
||||
def adding_self(update: Update, context: CallbackContext) -> None:
|
||||
def adding_self(update: Update, context: CallbackContext) -> str:
|
||||
"""Add information about youself."""
|
||||
context.user_data[CURRENT_LEVEL] = SELF
|
||||
text = 'Okay, please tell me about yourself.'
|
||||
@@ -116,10 +116,10 @@ def adding_self(update: Update, context: CallbackContext) -> None:
|
||||
return DESCRIBING_SELF
|
||||
|
||||
|
||||
def show_data(update: Update, context: CallbackContext) -> None:
|
||||
def show_data(update: Update, context: CallbackContext) -> str:
|
||||
"""Pretty print gathered data."""
|
||||
|
||||
def prettyprint(user_data, level):
|
||||
def prettyprint(user_data: Dict[str, Any], level: str) -> str:
|
||||
people = user_data.get(level)
|
||||
if not people:
|
||||
return '\nNo information yet.'
|
||||
@@ -151,14 +151,14 @@ def show_data(update: Update, context: CallbackContext) -> None:
|
||||
return SHOWING
|
||||
|
||||
|
||||
def stop(update: Update, context: CallbackContext) -> None:
|
||||
def stop(update: Update, _: CallbackContext) -> int:
|
||||
"""End Conversation by command."""
|
||||
update.message.reply_text('Okay, bye.')
|
||||
|
||||
return END
|
||||
|
||||
|
||||
def end(update: Update, context: CallbackContext) -> None:
|
||||
def end(update: Update, _: CallbackContext) -> int:
|
||||
"""End conversation from InlineKeyboardButton."""
|
||||
update.callback_query.answer()
|
||||
|
||||
@@ -169,7 +169,7 @@ def end(update: Update, context: CallbackContext) -> None:
|
||||
|
||||
|
||||
# Second level conversation callbacks
|
||||
def select_level(update: Update, context: CallbackContext) -> None:
|
||||
def select_level(update: Update, _: CallbackContext) -> str:
|
||||
"""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 = [
|
||||
@@ -190,7 +190,7 @@ def select_level(update: Update, context: CallbackContext) -> None:
|
||||
return SELECTING_LEVEL
|
||||
|
||||
|
||||
def select_gender(update: Update, context: CallbackContext) -> None:
|
||||
def select_gender(update: Update, context: CallbackContext) -> str:
|
||||
"""Choose to add mother or father."""
|
||||
level = update.callback_query.data
|
||||
context.user_data[CURRENT_LEVEL] = level
|
||||
@@ -217,7 +217,7 @@ def select_gender(update: Update, context: CallbackContext) -> None:
|
||||
return SELECTING_GENDER
|
||||
|
||||
|
||||
def end_second_level(update: Update, context: CallbackContext) -> None:
|
||||
def end_second_level(update: Update, context: CallbackContext) -> int:
|
||||
"""Return to top level conversation."""
|
||||
context.user_data[START_OVER] = True
|
||||
start(update, context)
|
||||
@@ -226,7 +226,7 @@ def end_second_level(update: Update, context: CallbackContext) -> None:
|
||||
|
||||
|
||||
# Third level callbacks
|
||||
def select_feature(update: Update, context: CallbackContext) -> None:
|
||||
def select_feature(update: Update, context: CallbackContext) -> str:
|
||||
"""Select a feature to update for the person."""
|
||||
buttons = [
|
||||
[
|
||||
@@ -253,7 +253,7 @@ def select_feature(update: Update, context: CallbackContext) -> None:
|
||||
return SELECTING_FEATURE
|
||||
|
||||
|
||||
def ask_for_input(update: Update, context: CallbackContext) -> None:
|
||||
def ask_for_input(update: Update, context: CallbackContext) -> str:
|
||||
"""Prompt user to input data for selected feature."""
|
||||
context.user_data[CURRENT_FEATURE] = update.callback_query.data
|
||||
text = 'Okay, tell me.'
|
||||
@@ -264,7 +264,7 @@ def ask_for_input(update: Update, context: CallbackContext) -> None:
|
||||
return TYPING
|
||||
|
||||
|
||||
def save_input(update: Update, context: CallbackContext) -> None:
|
||||
def save_input(update: Update, context: CallbackContext) -> str:
|
||||
"""Save input for feature and return to feature selection."""
|
||||
user_data = context.user_data
|
||||
user_data[FEATURES][user_data[CURRENT_FEATURE]] = update.message.text
|
||||
@@ -274,7 +274,7 @@ def save_input(update: Update, context: CallbackContext) -> None:
|
||||
return select_feature(update, context)
|
||||
|
||||
|
||||
def end_describing(update: Update, context: CallbackContext) -> None:
|
||||
def end_describing(update: Update, context: CallbackContext) -> int:
|
||||
"""End gathering of features and return to parent conversation."""
|
||||
user_data = context.user_data
|
||||
level = user_data[CURRENT_LEVEL]
|
||||
@@ -292,14 +292,14 @@ def end_describing(update: Update, context: CallbackContext) -> None:
|
||||
return END
|
||||
|
||||
|
||||
def stop_nested(update: Update, context: CallbackContext) -> None:
|
||||
def stop_nested(update: Update, _: CallbackContext) -> str:
|
||||
"""Completely end conversation from within nested conversation."""
|
||||
update.message.reply_text('Okay, bye.')
|
||||
|
||||
return STOPPING
|
||||
|
||||
|
||||
def main():
|
||||
def main() -> None:
|
||||
# Create the Updater and pass it your bot's token.
|
||||
updater = Updater("TOKEN")
|
||||
|
||||
|
||||
+12
-13
@@ -1,6 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=W0613, C0116
|
||||
# type: ignore[union-attr]
|
||||
# pylint: disable=C0116
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""
|
||||
@@ -24,7 +23,7 @@ logging.basicConfig(
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def msg(update: Update, context: CallbackContext) -> None:
|
||||
def msg(update: Update, _: CallbackContext) -> None:
|
||||
# If we received any passport data
|
||||
passport_data = update.message.passport_data
|
||||
if passport_data:
|
||||
@@ -65,19 +64,19 @@ def msg(update: Update, context: CallbackContext) -> None:
|
||||
actual_file.download()
|
||||
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)
|
||||
file.download()
|
||||
front_file = data.front_side.get_file()
|
||||
print(data.type, front_file)
|
||||
front_file.download()
|
||||
if data.type in ('driver_license' and 'identity_card'):
|
||||
if data.reverse_side:
|
||||
file = data.reverse_side.get_file()
|
||||
print(data.type, file)
|
||||
file.download()
|
||||
reverse_file = data.reverse_side.get_file()
|
||||
print(data.type, reverse_file)
|
||||
reverse_file.download()
|
||||
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()
|
||||
selfie_file = data.selfie.get_file()
|
||||
print(data.type, selfie_file)
|
||||
selfie_file.download()
|
||||
if data.type in (
|
||||
'passport',
|
||||
'driver_license',
|
||||
@@ -96,7 +95,7 @@ def msg(update: Update, context: CallbackContext) -> None:
|
||||
actual_file.download()
|
||||
|
||||
|
||||
def main():
|
||||
def main() -> None:
|
||||
"""Start the bot."""
|
||||
# Create the Updater and pass it your token and private key
|
||||
updater = Updater("TOKEN", private_key=open('private.key', 'rb').read())
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=W0613, C0116
|
||||
# type: ignore[union-attr]
|
||||
# pylint: disable=C0116
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""
|
||||
@@ -28,7 +27,7 @@ logging.basicConfig(
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def start_callback(update: Update, context: CallbackContext) -> None:
|
||||
def start_callback(update: Update, _: 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)
|
||||
@@ -91,7 +90,7 @@ def start_without_shipping_callback(update: Update, context: CallbackContext) ->
|
||||
)
|
||||
|
||||
|
||||
def shipping_callback(update: Update, context: CallbackContext) -> None:
|
||||
def shipping_callback(update: Update, _: CallbackContext) -> None:
|
||||
query = update.shipping_query
|
||||
# check the payload, is this from your bot?
|
||||
if query.invoice_payload != 'Custom-Payload':
|
||||
@@ -109,7 +108,7 @@ def shipping_callback(update: Update, context: CallbackContext) -> None:
|
||||
|
||||
|
||||
# after (optional) shipping, it's the pre-checkout
|
||||
def precheckout_callback(update: Update, context: CallbackContext) -> None:
|
||||
def precheckout_callback(update: Update, _: CallbackContext) -> None:
|
||||
query = update.pre_checkout_query
|
||||
# check the payload, is this from your bot?
|
||||
if query.invoice_payload != 'Custom-Payload':
|
||||
@@ -120,12 +119,12 @@ def precheckout_callback(update: Update, context: CallbackContext) -> None:
|
||||
|
||||
|
||||
# finally, after contacting the payment provider...
|
||||
def successful_payment_callback(update: Update, context: CallbackContext) -> None:
|
||||
def successful_payment_callback(update: Update, _: CallbackContext) -> None:
|
||||
# do something after successfully receiving payment?
|
||||
update.message.reply_text("Thank you for your payment!")
|
||||
|
||||
|
||||
def main():
|
||||
def main() -> None:
|
||||
# Create the Updater and pass it your bot's token.
|
||||
updater = Updater("TOKEN")
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=W0613, C0116, C0103
|
||||
# type: ignore[union-attr]
|
||||
# pylint: disable=C0116
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""
|
||||
@@ -16,6 +15,7 @@ bot.
|
||||
"""
|
||||
|
||||
import logging
|
||||
from typing import Dict
|
||||
|
||||
from telegram import ReplyKeyboardMarkup, Update
|
||||
from telegram.ext import (
|
||||
@@ -46,7 +46,7 @@ reply_keyboard = [
|
||||
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():
|
||||
@@ -55,7 +55,7 @@ def facts_to_str(user_data):
|
||||
return "\n".join(facts).join(['\n', '\n'])
|
||||
|
||||
|
||||
def start(update: Update, context: CallbackContext) -> None:
|
||||
def start(update: Update, context: CallbackContext) -> int:
|
||||
reply_text = "Hi! My name is Doctor Botter."
|
||||
if context.user_data:
|
||||
reply_text += (
|
||||
@@ -72,7 +72,7 @@ def start(update: Update, context: CallbackContext) -> None:
|
||||
return CHOOSING
|
||||
|
||||
|
||||
def regular_choice(update: Update, context: CallbackContext) -> None:
|
||||
def regular_choice(update: Update, context: CallbackContext) -> int:
|
||||
text = update.message.text.lower()
|
||||
context.user_data['choice'] = text
|
||||
if context.user_data.get(text):
|
||||
@@ -86,7 +86,7 @@ def regular_choice(update: Update, context: CallbackContext) -> None:
|
||||
return TYPING_REPLY
|
||||
|
||||
|
||||
def custom_choice(update: Update, context: CallbackContext) -> None:
|
||||
def custom_choice(update: Update, _: CallbackContext) -> int:
|
||||
update.message.reply_text(
|
||||
'Alright, please send me the category first, ' 'for example "Most impressive skill"'
|
||||
)
|
||||
@@ -94,7 +94,7 @@ def custom_choice(update: Update, context: CallbackContext) -> None:
|
||||
return TYPING_CHOICE
|
||||
|
||||
|
||||
def received_information(update: Update, context: CallbackContext) -> None:
|
||||
def received_information(update: Update, context: CallbackContext) -> int:
|
||||
text = update.message.text
|
||||
category = context.user_data['choice']
|
||||
context.user_data[category] = text.lower()
|
||||
@@ -117,23 +117,23 @@ def show_data(update: Update, context: CallbackContext) -> None:
|
||||
)
|
||||
|
||||
|
||||
def done(update: Update, context: CallbackContext) -> None:
|
||||
def done(update: Update, context: CallbackContext) -> int:
|
||||
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!"
|
||||
"I learned these facts about you:" f"{facts_to_str(context.user_data)} Until next time!"
|
||||
)
|
||||
return ConversationHandler.END
|
||||
|
||||
|
||||
def main():
|
||||
def main() -> None:
|
||||
# Create the Updater and pass it your bot's token.
|
||||
pp = PicklePersistence(filename='conversationbot')
|
||||
updater = Updater("TOKEN", persistence=pp)
|
||||
persistence = PicklePersistence(filename='conversationbot')
|
||||
updater = Updater("TOKEN", persistence=persistence)
|
||||
|
||||
# Get the dispatcher to register handlers
|
||||
dp = updater.dispatcher
|
||||
dispatcher = updater.dispatcher
|
||||
|
||||
# Add conversation handler with the states CHOOSING, TYPING_CHOICE and TYPING_REPLY
|
||||
conv_handler = ConversationHandler(
|
||||
@@ -162,10 +162,10 @@ def main():
|
||||
persistent=True,
|
||||
)
|
||||
|
||||
dp.add_handler(conv_handler)
|
||||
dispatcher.add_handler(conv_handler)
|
||||
|
||||
show_data_handler = CommandHandler('show_data', show_data)
|
||||
dp.add_handler(show_data_handler)
|
||||
dispatcher.add_handler(show_data_handler)
|
||||
|
||||
# Start the Bot
|
||||
updater.start_polling()
|
||||
|
||||
+6
-7
@@ -1,6 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=W0613, C0116
|
||||
# type: ignore[union-attr]
|
||||
# pylint: disable=C0116
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""
|
||||
@@ -35,7 +34,7 @@ logging.basicConfig(
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def start(update: Update, context: CallbackContext) -> None:
|
||||
def start(update: Update, _: 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'
|
||||
@@ -121,7 +120,7 @@ def receive_quiz_answer(update: Update, context: CallbackContext) -> None:
|
||||
context.bot.stop_poll(quiz_data["chat_id"], quiz_data["message_id"])
|
||||
|
||||
|
||||
def preview(update: Update, context: CallbackContext) -> None:
|
||||
def preview(update: Update, _: 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())]]
|
||||
@@ -132,7 +131,7 @@ def preview(update: Update, context: CallbackContext) -> None:
|
||||
)
|
||||
|
||||
|
||||
def receive_poll(update: Update, context: CallbackContext) -> None:
|
||||
def receive_poll(update: Update, _: 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
|
||||
@@ -146,9 +145,9 @@ def receive_poll(update: Update, context: CallbackContext) -> None:
|
||||
)
|
||||
|
||||
|
||||
def help_handler(update: Update, context: CallbackContext) -> None:
|
||||
def help_handler(update: Update, _: CallbackContext) -> None:
|
||||
"""Display a help message"""
|
||||
update.message.reply_text("Use /quiz, /poll or /preview to test this " "bot.")
|
||||
update.message.reply_text("Use /quiz, /poll or /preview to test this bot.")
|
||||
|
||||
|
||||
def main() -> None:
|
||||
|
||||
@@ -39,7 +39,7 @@ def main() -> NoReturn:
|
||||
sleep(1)
|
||||
except Unauthorized:
|
||||
# The user has removed or blocked the bot.
|
||||
UPDATE_ID += 1 # type: ignore[operator]
|
||||
UPDATE_ID += 1
|
||||
|
||||
|
||||
def echo(bot: telegram.Bot) -> None:
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=W0613, C0116
|
||||
# type: ignore[union-attr]
|
||||
# pylint: disable=C0116
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""
|
||||
@@ -34,17 +33,17 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
# 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:
|
||||
def start(update: Update, _: CallbackContext) -> None:
|
||||
update.message.reply_text('Hi! Use /set <seconds> to set a timer')
|
||||
|
||||
|
||||
def alarm(context):
|
||||
def alarm(context: CallbackContext) -> None:
|
||||
"""Send the alarm message."""
|
||||
job = context.job
|
||||
context.bot.send_message(job.context, text='Beep!')
|
||||
|
||||
|
||||
def remove_job_if_exists(name, context):
|
||||
def remove_job_if_exists(name: str, context: CallbackContext) -> bool:
|
||||
"""Remove job with given name. Returns whether job was removed."""
|
||||
current_jobs = context.job_queue.get_jobs_by_name(name)
|
||||
if not current_jobs:
|
||||
@@ -84,7 +83,7 @@ def unset(update: Update, context: CallbackContext) -> None:
|
||||
update.message.reply_text(text)
|
||||
|
||||
|
||||
def main():
|
||||
def main() -> None:
|
||||
"""Run bot."""
|
||||
# Create the Updater and pass it your bot's token.
|
||||
updater = Updater("TOKEN")
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
# cryptography is an optional dependency, but running the tests properly requires it
|
||||
cryptography!=3.4,!=3.4.1,!=3.4.2,!=3.4.3
|
||||
|
||||
pre-commit
|
||||
# Make sure that the versions specified here match the pre-commit settings
|
||||
# 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
|
||||
pylint==2.7.2
|
||||
mypy==0.812
|
||||
pyupgrade==2.10.0
|
||||
|
||||
pytest==4.2.0
|
||||
# Need older attrs version for pytest 4.2.0
|
||||
attrs==19.1.0
|
||||
pytest==6.2.2
|
||||
|
||||
flaky
|
||||
beautifulsoup4
|
||||
|
||||
+2
-1
@@ -1,5 +1,6 @@
|
||||
# Make sure to install those as additional_dependencies in the
|
||||
# pre-commit hooks for pylint & mypy
|
||||
certifi
|
||||
cryptography
|
||||
# only telegram.ext: # Keep this line here; used in setup(-raw).py
|
||||
tornado>=5.1
|
||||
APScheduler==3.6.3
|
||||
|
||||
@@ -27,7 +27,9 @@ addopts = --no-success-flaky-report -rsxX
|
||||
filterwarnings =
|
||||
error
|
||||
ignore::DeprecationWarning
|
||||
ignore::telegram.utils.deprecate.TelegramDeprecationWarning
|
||||
; Unfortunately due to https://github.com/pytest-dev/pytest/issues/8343 we can't have this here
|
||||
; and instead do a trick directly in tests/conftest.py
|
||||
; ignore::telegram.utils.deprecate.TelegramDeprecationWarning
|
||||
|
||||
[coverage:run]
|
||||
branch = True
|
||||
@@ -59,6 +61,10 @@ ignore_errors = True
|
||||
[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
|
||||
|
||||
# type hinting for asyncio in webhookhandler is a bit tricky because it depends on the OS
|
||||
[mypy-telegram.ext.utils.webhookhandler]
|
||||
warn_unused_ignores = False
|
||||
|
||||
[mypy-urllib3.*]
|
||||
ignore_missing_imports = True
|
||||
|
||||
|
||||
@@ -53,8 +53,9 @@ def get_setup_kwargs(raw=False):
|
||||
|
||||
fn = os.path.join('telegram', 'version.py')
|
||||
with open(fn) as fh:
|
||||
code = compile(fh.read(), fn, 'exec')
|
||||
exec(code)
|
||||
for line in fh.readlines():
|
||||
if line.startswith('__version__'):
|
||||
exec(line)
|
||||
|
||||
with open(readme, 'r', encoding='utf-8') as fd:
|
||||
|
||||
@@ -84,7 +85,9 @@ def get_setup_kwargs(raw=False):
|
||||
install_requires=requirements,
|
||||
extras_require={
|
||||
'json': 'ujson',
|
||||
'socks': 'PySocks'
|
||||
'socks': 'PySocks',
|
||||
# 3.4-3.4.3 contained some cyclical import bugs
|
||||
'passport': 'cryptography!=3.4,!=3.4.1,!=3.4.2,!=3.4.3',
|
||||
},
|
||||
include_package_data=True,
|
||||
classifiers=[
|
||||
|
||||
+87
-78
@@ -24,7 +24,9 @@ from .user import User
|
||||
from .files.chatphoto import ChatPhoto
|
||||
from .chat import Chat
|
||||
from .chatlocation import ChatLocation
|
||||
from .chatinvitelink import ChatInviteLink
|
||||
from .chatmember import ChatMember
|
||||
from .chatmemberupdated import ChatMemberUpdated
|
||||
from .chatpermissions import ChatPermissions
|
||||
from .files.photosize import PhotoSize
|
||||
from .files.audio import Audio
|
||||
@@ -40,8 +42,8 @@ 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 .keyboardbutton import KeyboardButton
|
||||
from .replymarkup import ReplyMarkup
|
||||
from .replykeyboardmarkup import ReplyKeyboardMarkup
|
||||
from .replykeyboardremove import ReplyKeyboardRemove
|
||||
@@ -54,6 +56,7 @@ from .messageentity import MessageEntity
|
||||
from .messageid import MessageId
|
||||
from .games.game import Game
|
||||
from .poll import Poll, PollOption, PollAnswer
|
||||
from .voicechat import VoiceChatStarted, VoiceChatEnded, VoiceChatParticipantsInvited
|
||||
from .loginurl import LoginUrl
|
||||
from .proximityalerttriggered import ProximityAlertTriggered
|
||||
from .games.callbackgame import CallbackGame
|
||||
@@ -68,6 +71,7 @@ from .passport.encryptedpassportelement import EncryptedPassportElement
|
||||
from .passport.passportdata import PassportData
|
||||
from .inline.inlinekeyboardbutton import InlineKeyboardButton
|
||||
from .inline.inlinekeyboardmarkup import InlineKeyboardMarkup
|
||||
from .messageautodeletetimerchanged import MessageAutoDeleteTimerChanged
|
||||
from .message import Message
|
||||
from .callbackquery import CallbackQuery
|
||||
from .choseninlineresult import ChosenInlineResult
|
||||
@@ -139,32 +143,48 @@ from .passport.credentials import (
|
||||
Credentials,
|
||||
DataCredentials,
|
||||
SecureData,
|
||||
SecureValue,
|
||||
FileCredentials,
|
||||
TelegramDecryptionError,
|
||||
)
|
||||
from .bot import Bot
|
||||
from .version import __version__ # noqa: F401
|
||||
from .version import __version__, bot_api_version # noqa: F401
|
||||
|
||||
__author__ = 'devs@python-telegram-bot.org'
|
||||
|
||||
__all__ = [
|
||||
__all__ = ( # Keep this alphabetically ordered
|
||||
'Animation',
|
||||
'Audio',
|
||||
'Bot',
|
||||
'Chat',
|
||||
'ChatMember',
|
||||
'ChatPermissions',
|
||||
'ChatAction',
|
||||
'ChosenInlineResult',
|
||||
'BotCommand',
|
||||
'CallbackGame',
|
||||
'CallbackQuery',
|
||||
'Chat',
|
||||
'ChatAction',
|
||||
'ChatInviteLink',
|
||||
'ChatLocation',
|
||||
'ChatMember',
|
||||
'ChatMemberUpdated',
|
||||
'ChatPermissions',
|
||||
'ChatPhoto',
|
||||
'ChosenInlineResult',
|
||||
'Contact',
|
||||
'Credentials',
|
||||
'DataCredentials',
|
||||
'Dice',
|
||||
'Document',
|
||||
'EncryptedCredentials',
|
||||
'EncryptedPassportElement',
|
||||
'File',
|
||||
'FileCredentials',
|
||||
'ForceReply',
|
||||
'Game',
|
||||
'GameHighScore',
|
||||
'IdDocumentData',
|
||||
'InlineKeyboardButton',
|
||||
'InlineKeyboardMarkup',
|
||||
'InlineQuery',
|
||||
'InlineQueryResult',
|
||||
'InlineQueryResult',
|
||||
'InlineQueryResultArticle',
|
||||
'InlineQueryResultAudio',
|
||||
'InlineQueryResultCachedAudio',
|
||||
@@ -177,6 +197,7 @@ __all__ = [
|
||||
'InlineQueryResultCachedVoice',
|
||||
'InlineQueryResultContact',
|
||||
'InlineQueryResultDocument',
|
||||
'InlineQueryResultGame',
|
||||
'InlineQueryResultGif',
|
||||
'InlineQueryResultLocation',
|
||||
'InlineQueryResultMpeg4Gif',
|
||||
@@ -184,28 +205,71 @@ __all__ = [
|
||||
'InlineQueryResultVenue',
|
||||
'InlineQueryResultVideo',
|
||||
'InlineQueryResultVoice',
|
||||
'InlineQueryResultGame',
|
||||
'InputContactMessageContent',
|
||||
'InputFile',
|
||||
'InputLocationMessageContent',
|
||||
'InputMedia',
|
||||
'InputMediaAnimation',
|
||||
'InputMediaAudio',
|
||||
'InputMediaDocument',
|
||||
'InputMediaPhoto',
|
||||
'InputMediaVideo',
|
||||
'InputMessageContent',
|
||||
'InputTextMessageContent',
|
||||
'InputVenueMessageContent',
|
||||
'Invoice',
|
||||
'KeyboardButton',
|
||||
'KeyboardButtonPollType',
|
||||
'LabeledPrice',
|
||||
'Location',
|
||||
'ChatLocation',
|
||||
'ProximityAlertTriggered',
|
||||
'EncryptedCredentials',
|
||||
'PassportFile',
|
||||
'EncryptedPassportElement',
|
||||
'PassportData',
|
||||
'LoginUrl',
|
||||
'MAX_CAPTION_LENGTH',
|
||||
'MAX_FILESIZE_DOWNLOAD',
|
||||
'MAX_FILESIZE_UPLOAD',
|
||||
'MAX_MESSAGES_PER_MINUTE_PER_GROUP',
|
||||
'MAX_MESSAGES_PER_SECOND',
|
||||
'MAX_MESSAGES_PER_SECOND_PER_CHAT',
|
||||
'MAX_MESSAGE_LENGTH',
|
||||
'MaskPosition',
|
||||
'Message',
|
||||
'MessageAutoDeleteTimerChanged',
|
||||
'MessageEntity',
|
||||
'MessageId',
|
||||
'OrderInfo',
|
||||
'ParseMode',
|
||||
'PassportData',
|
||||
'PassportElementError',
|
||||
'PassportElementErrorDataField',
|
||||
'PassportElementErrorFile',
|
||||
'PassportElementErrorFiles',
|
||||
'PassportElementErrorFrontSide',
|
||||
'PassportElementErrorReverseSide',
|
||||
'PassportElementErrorSelfie',
|
||||
'PassportElementErrorTranslationFile',
|
||||
'PassportElementErrorTranslationFiles',
|
||||
'PassportElementErrorUnspecified',
|
||||
'PassportFile',
|
||||
'PersonalDetails',
|
||||
'PhotoSize',
|
||||
'ReplyKeyboardRemove',
|
||||
'Poll',
|
||||
'PollAnswer',
|
||||
'PollOption',
|
||||
'PreCheckoutQuery',
|
||||
'ProximityAlertTriggered',
|
||||
'ReplyKeyboardMarkup',
|
||||
'ReplyKeyboardRemove',
|
||||
'ReplyMarkup',
|
||||
'ResidentialAddress',
|
||||
'SUPPORTED_WEBHOOK_PORTS',
|
||||
'SecureData',
|
||||
'SecureValue',
|
||||
'ShippingAddress',
|
||||
'ShippingOption',
|
||||
'ShippingQuery',
|
||||
'Sticker',
|
||||
'StickerSet',
|
||||
'SuccessfulPayment',
|
||||
'TelegramDecryptionError',
|
||||
'TelegramError',
|
||||
'TelegramObject',
|
||||
'Update',
|
||||
@@ -213,65 +277,10 @@ __all__ = [
|
||||
'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',
|
||||
]
|
||||
'Voice',
|
||||
'VoiceChatStarted',
|
||||
'VoiceChatEnded',
|
||||
'VoiceChatParticipantsInvited',
|
||||
'WebhookInfo',
|
||||
)
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#
|
||||
# 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
|
||||
# pylint: disable=C0114
|
||||
import subprocess
|
||||
import sys
|
||||
from typing import Optional
|
||||
@@ -24,6 +24,7 @@ from typing import Optional
|
||||
import certifi
|
||||
|
||||
from . import __version__ as telegram_ver
|
||||
from .constants import BOT_API_VERSION
|
||||
|
||||
|
||||
def _git_revision() -> Optional[str]:
|
||||
@@ -39,6 +40,7 @@ def _git_revision() -> Optional[str]:
|
||||
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'Bot API {BOT_API_VERSION}')
|
||||
print(f'certifi {certifi.__version__}') # type: ignore[attr-defined]
|
||||
sys_version = sys.version.replace('\n', ' ')
|
||||
print(f'Python {sys_version}')
|
||||
|
||||
+2
-4
@@ -46,15 +46,13 @@ class TelegramObject:
|
||||
|
||||
@staticmethod
|
||||
def parse_data(data: Optional[JSONDict]) -> Optional[JSONDict]:
|
||||
if not data:
|
||||
return None
|
||||
return data.copy()
|
||||
return None if data is None else data.copy()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls: Type[TO], data: Optional[JSONDict], bot: 'Bot') -> Optional[TO]:
|
||||
data = cls.parse_data(data)
|
||||
|
||||
if not data:
|
||||
if data is None:
|
||||
return None
|
||||
|
||||
if cls == TelegramObject:
|
||||
|
||||
+674
-419
File diff suppressed because it is too large
Load Diff
+24
-23
@@ -21,7 +21,8 @@
|
||||
from typing import TYPE_CHECKING, Any, List, Optional, Union, Tuple, ClassVar
|
||||
|
||||
from telegram import Message, TelegramObject, User, Location, ReplyMarkup, constants
|
||||
from telegram.utils.types import JSONDict
|
||||
from telegram.utils.helpers import DEFAULT_NONE
|
||||
from telegram.utils.types import JSONDict, ODVInput, DVInput
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import (
|
||||
@@ -46,7 +47,7 @@ class CallbackQuery(TelegramObject):
|
||||
considered equal, if their :attr:`id` is equal.
|
||||
|
||||
Note:
|
||||
* In Python `from` is a reserved word, use `from_user` instead.
|
||||
* 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.
|
||||
* 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
|
||||
@@ -128,7 +129,7 @@ class CallbackQuery(TelegramObject):
|
||||
show_alert: bool = False,
|
||||
url: str = None,
|
||||
cache_time: int = None,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> bool:
|
||||
"""Shortcut for::
|
||||
@@ -155,10 +156,10 @@ class CallbackQuery(TelegramObject):
|
||||
def edit_message_text(
|
||||
self,
|
||||
text: str,
|
||||
parse_mode: str = None,
|
||||
disable_web_page_preview: bool = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
disable_web_page_preview: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_markup: 'InlineKeyboardMarkup' = None,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
) -> Union[Message, bool]:
|
||||
@@ -206,8 +207,8 @@ class CallbackQuery(TelegramObject):
|
||||
self,
|
||||
caption: str = None,
|
||||
reply_markup: 'InlineKeyboardMarkup' = None,
|
||||
timeout: float = None,
|
||||
parse_mode: str = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
caption_entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
) -> Union[Message, bool]:
|
||||
@@ -253,7 +254,7 @@ class CallbackQuery(TelegramObject):
|
||||
def edit_message_reply_markup(
|
||||
self,
|
||||
reply_markup: Optional['InlineKeyboardMarkup'] = None,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> Union[Message, bool]:
|
||||
"""Shortcut for either::
|
||||
@@ -300,7 +301,7 @@ class CallbackQuery(TelegramObject):
|
||||
self,
|
||||
media: 'InputMedia' = None,
|
||||
reply_markup: 'InlineKeyboardMarkup' = None,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> Union[Message, bool]:
|
||||
"""Shortcut for either::
|
||||
@@ -343,7 +344,7 @@ class CallbackQuery(TelegramObject):
|
||||
longitude: float = None,
|
||||
location: Location = None,
|
||||
reply_markup: 'InlineKeyboardMarkup' = None,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
horizontal_accuracy: float = None,
|
||||
heading: int = None,
|
||||
@@ -398,7 +399,7 @@ class CallbackQuery(TelegramObject):
|
||||
def stop_message_live_location(
|
||||
self,
|
||||
reply_markup: 'InlineKeyboardMarkup' = None,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> Union[Message, bool]:
|
||||
"""Shortcut for either::
|
||||
@@ -441,7 +442,7 @@ class CallbackQuery(TelegramObject):
|
||||
score: int,
|
||||
force: bool = None,
|
||||
disable_edit_message: bool = None,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> Union[Message, bool]:
|
||||
"""Shortcut for either::
|
||||
@@ -485,7 +486,7 @@ class CallbackQuery(TelegramObject):
|
||||
def get_game_high_scores(
|
||||
self,
|
||||
user_id: Union[int, str],
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> List['GameHighScore']:
|
||||
"""Shortcut for either::
|
||||
@@ -521,7 +522,7 @@ class CallbackQuery(TelegramObject):
|
||||
|
||||
def delete_message(
|
||||
self,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> bool:
|
||||
"""Shortcut for::
|
||||
@@ -542,8 +543,8 @@ class CallbackQuery(TelegramObject):
|
||||
|
||||
def pin_message(
|
||||
self,
|
||||
disable_notification: bool = None,
|
||||
timeout: float = None,
|
||||
disable_notification: ODVInput[bool] = DEFAULT_NONE,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> bool:
|
||||
"""Shortcut for::
|
||||
@@ -568,7 +569,7 @@ class CallbackQuery(TelegramObject):
|
||||
|
||||
def unpin_message(
|
||||
self,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> bool:
|
||||
"""Shortcut for::
|
||||
@@ -594,13 +595,13 @@ class CallbackQuery(TelegramObject):
|
||||
self,
|
||||
chat_id: Union[int, str],
|
||||
caption: str = None,
|
||||
parse_mode: str = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_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,
|
||||
disable_notification: DVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: int = None,
|
||||
allow_sending_without_reply: DVInput[bool] = DEFAULT_NONE,
|
||||
reply_markup: ReplyMarkup = None,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> 'MessageId':
|
||||
"""Shortcut for::
|
||||
|
||||
+241
-116
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=C0103,W0622
|
||||
# pylint: disable=W0622
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2021
|
||||
@@ -22,16 +22,17 @@ from datetime import datetime
|
||||
from typing import TYPE_CHECKING, List, Optional, ClassVar, Union, Tuple, Any
|
||||
|
||||
from telegram import ChatPhoto, TelegramObject, constants
|
||||
from telegram.utils.types import JSONDict, FileInput
|
||||
from telegram.utils.types import JSONDict, FileInput, ODVInput, DVInput
|
||||
|
||||
from .chatpermissions import ChatPermissions
|
||||
from .chatlocation import ChatLocation
|
||||
from .utils.helpers import DefaultValue, DEFAULT_NONE
|
||||
from .utils.helpers import DEFAULT_NONE, DEFAULT_20
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import (
|
||||
Bot,
|
||||
ChatMember,
|
||||
ChatInviteLink,
|
||||
Message,
|
||||
MessageId,
|
||||
ReplyMarkup,
|
||||
@@ -80,10 +81,8 @@ class Chat(TelegramObject):
|
||||
:meth:`telegram.Bot.get_chat`.
|
||||
description (:obj:`str`, optional): Description, for groups, supergroups and channel chats.
|
||||
Returned only in :meth:`telegram.Bot.get_chat`.
|
||||
invite_link (:obj:`str`, optional): Chat invite link, for groups, supergroups and channel
|
||||
chats. Each administrator in a chat generates their own invite links, so the bot must
|
||||
first generate the link using ``export_chat_invite_link()``. Returned only
|
||||
in :meth:`telegram.Bot.get_chat`.
|
||||
invite_link (:obj:`str`, optional): Primary invite link, for groups, supergroups and
|
||||
channel. Returned only in :meth:`telegram.Bot.get_chat`.
|
||||
pinned_message (:class:`telegram.Message`, optional): The most recent pinned message
|
||||
(by sending date). Returned only in :meth:`telegram.Bot.get_chat`.
|
||||
permissions (:class:`telegram.ChatPermissions`): Optional. Default chat member permissions,
|
||||
@@ -91,6 +90,11 @@ class Chat(TelegramObject):
|
||||
slow_mode_delay (:obj:`int`, optional): For supergroups, the minimum allowed delay between
|
||||
consecutive messages sent by each unprivileged user.
|
||||
Returned only in :meth:`telegram.Bot.get_chat`.
|
||||
message_auto_delete_time (:obj:`int`, optional): The time after which all messages sent to
|
||||
the chat will be automatically deleted; in seconds. Returned only in
|
||||
:meth:`telegram.Bot.get_chat`.
|
||||
|
||||
.. versionadded:: 13.4
|
||||
bot (:class:`telegram.Bot`, optional): The Bot to use for instance methods.
|
||||
sticker_set_name (:obj:`str`, optional): For supergroups, name of group sticker set.
|
||||
Returned only in :meth:`telegram.Bot.get_chat`.
|
||||
@@ -114,7 +118,8 @@ class Chat(TelegramObject):
|
||||
bio (:obj:`str`): Optional. Bio of the other party in a private chat. Returned only in
|
||||
:meth:`telegram.Bot.get_chat`.
|
||||
description (:obj:`str`): Optional. Description, for groups, supergroups and channel chats.
|
||||
invite_link (:obj:`str`): Optional. Chat invite link, for supergroups and channel chats.
|
||||
invite_link (:obj:`str`): Optional. Primary invite link, for groups, supergroups and
|
||||
channel. Returned only in :meth:`telegram.Bot.get_chat`.
|
||||
pinned_message (:class:`telegram.Message`): Optional. The most recent pinned message
|
||||
(by sending date). Returned only in :meth:`telegram.Bot.get_chat`.
|
||||
permissions (:class:`telegram.ChatPermissions`): Optional. Default chat member permissions,
|
||||
@@ -122,6 +127,11 @@ class Chat(TelegramObject):
|
||||
slow_mode_delay (:obj:`int`): Optional. For supergroups, the minimum allowed delay between
|
||||
consecutive messages sent by each unprivileged user. Returned only in
|
||||
:meth:`telegram.Bot.get_chat`.
|
||||
message_auto_delete_time (:obj:`int`): Optional. The time after which all messages sent to
|
||||
the chat will be automatically deleted; in seconds. Returned only in
|
||||
:meth:`telegram.Bot.get_chat`.
|
||||
|
||||
.. versionadded:: 13.4
|
||||
sticker_set_name (:obj:`str`): Optional. For supergroups, name of Group sticker set.
|
||||
can_set_sticker_set (:obj:`bool`): Optional. :obj:`True`, if the bot can change group the
|
||||
sticker set.
|
||||
@@ -162,10 +172,11 @@ class Chat(TelegramObject):
|
||||
bio: str = None,
|
||||
linked_chat_id: int = None,
|
||||
location: ChatLocation = None,
|
||||
message_auto_delete_time: int = None,
|
||||
**_kwargs: Any,
|
||||
):
|
||||
# Required
|
||||
self.id = int(id)
|
||||
self.id = int(id) # pylint: disable=C0103
|
||||
self.type = type
|
||||
# Optionals
|
||||
self.title = title
|
||||
@@ -181,6 +192,9 @@ class Chat(TelegramObject):
|
||||
self.pinned_message = pinned_message
|
||||
self.permissions = permissions
|
||||
self.slow_mode_delay = slow_mode_delay
|
||||
self.message_auto_delete_time = (
|
||||
int(message_auto_delete_time) if message_auto_delete_time is not None else None
|
||||
)
|
||||
self.sticker_set_name = sticker_set_name
|
||||
self.can_set_sticker_set = can_set_sticker_set
|
||||
self.linked_chat_id = linked_chat_id
|
||||
@@ -216,7 +230,7 @@ class Chat(TelegramObject):
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: JSONDict, bot: 'Bot') -> Optional['Chat']:
|
||||
def de_json(cls, data: Optional[JSONDict], bot: 'Bot') -> Optional['Chat']:
|
||||
data = cls.parse_data(data)
|
||||
|
||||
if not data:
|
||||
@@ -231,7 +245,7 @@ class Chat(TelegramObject):
|
||||
|
||||
return cls(bot=bot, **data)
|
||||
|
||||
def leave(self, timeout: float = None, api_kwargs: JSONDict = None) -> bool:
|
||||
def leave(self, timeout: ODVInput[float] = DEFAULT_NONE, api_kwargs: JSONDict = None) -> bool:
|
||||
"""Shortcut for::
|
||||
|
||||
bot.leave_chat(update.effective_chat.id, *args, **kwargs)
|
||||
@@ -249,7 +263,7 @@ class Chat(TelegramObject):
|
||||
)
|
||||
|
||||
def get_administrators(
|
||||
self, timeout: float = None, api_kwargs: JSONDict = None
|
||||
self, timeout: ODVInput[float] = DEFAULT_NONE, api_kwargs: JSONDict = None
|
||||
) -> List['ChatMember']:
|
||||
"""Shortcut for::
|
||||
|
||||
@@ -271,7 +285,9 @@ class Chat(TelegramObject):
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
def get_members_count(self, timeout: float = None, api_kwargs: JSONDict = None) -> int:
|
||||
def get_members_count(
|
||||
self, timeout: ODVInput[float] = DEFAULT_NONE, api_kwargs: JSONDict = None
|
||||
) -> int:
|
||||
"""Shortcut for::
|
||||
|
||||
bot.get_chat_members_count(update.effective_chat.id, *args, **kwargs)
|
||||
@@ -292,7 +308,7 @@ class Chat(TelegramObject):
|
||||
def get_member(
|
||||
self,
|
||||
user_id: Union[str, int],
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> 'ChatMember':
|
||||
"""Shortcut for::
|
||||
@@ -315,9 +331,10 @@ class Chat(TelegramObject):
|
||||
def kick_member(
|
||||
self,
|
||||
user_id: Union[str, int],
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
until_date: Union[int, datetime] = None,
|
||||
api_kwargs: JSONDict = None,
|
||||
revoke_messages: bool = None,
|
||||
) -> bool:
|
||||
"""Shortcut for::
|
||||
|
||||
@@ -341,12 +358,13 @@ class Chat(TelegramObject):
|
||||
timeout=timeout,
|
||||
until_date=until_date,
|
||||
api_kwargs=api_kwargs,
|
||||
revoke_messages=revoke_messages,
|
||||
)
|
||||
|
||||
def unban_member(
|
||||
self,
|
||||
user_id: Union[str, int],
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
only_if_banned: bool = None,
|
||||
) -> bool:
|
||||
@@ -379,9 +397,11 @@ class Chat(TelegramObject):
|
||||
can_restrict_members: bool = None,
|
||||
can_pin_messages: bool = None,
|
||||
can_promote_members: bool = None,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
is_anonymous: bool = None,
|
||||
can_manage_chat: bool = None,
|
||||
can_manage_voice_chats: bool = None,
|
||||
) -> bool:
|
||||
"""Shortcut for::
|
||||
|
||||
@@ -410,6 +430,8 @@ class Chat(TelegramObject):
|
||||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
is_anonymous=is_anonymous,
|
||||
can_manage_chat=can_manage_chat,
|
||||
can_manage_voice_chats=can_manage_voice_chats,
|
||||
)
|
||||
|
||||
def restrict_member(
|
||||
@@ -417,7 +439,7 @@ class Chat(TelegramObject):
|
||||
user_id: Union[str, int],
|
||||
permissions: ChatPermissions,
|
||||
until_date: Union[int, datetime] = None,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> bool:
|
||||
"""Shortcut for::
|
||||
@@ -445,7 +467,7 @@ class Chat(TelegramObject):
|
||||
def set_permissions(
|
||||
self,
|
||||
permissions: ChatPermissions,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> bool:
|
||||
"""Shortcut for::
|
||||
@@ -470,7 +492,7 @@ class Chat(TelegramObject):
|
||||
self,
|
||||
user_id: Union[int, str],
|
||||
custom_title: str,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> bool:
|
||||
"""Shortcut for::
|
||||
@@ -494,9 +516,9 @@ class Chat(TelegramObject):
|
||||
|
||||
def pin_message(
|
||||
self,
|
||||
message_id: Union[str, int],
|
||||
disable_notification: bool = None,
|
||||
timeout: float = None,
|
||||
message_id: int,
|
||||
disable_notification: ODVInput[bool] = DEFAULT_NONE,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> bool:
|
||||
"""Shortcut for::
|
||||
@@ -522,9 +544,9 @@ class Chat(TelegramObject):
|
||||
|
||||
def unpin_message(
|
||||
self,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
message_id: Union[str, int] = None,
|
||||
message_id: int = None,
|
||||
) -> bool:
|
||||
"""Shortcut for::
|
||||
|
||||
@@ -548,7 +570,7 @@ class Chat(TelegramObject):
|
||||
|
||||
def unpin_all_messages(
|
||||
self,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> bool:
|
||||
"""Shortcut for::
|
||||
@@ -573,14 +595,14 @@ class Chat(TelegramObject):
|
||||
def send_message(
|
||||
self,
|
||||
text: str,
|
||||
parse_mode: str = None,
|
||||
disable_web_page_preview: bool = None,
|
||||
disable_notification: bool = False,
|
||||
reply_to_message_id: Union[int, str] = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
disable_web_page_preview: ODVInput[bool] = DEFAULT_NONE,
|
||||
disable_notification: DVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: int = None,
|
||||
reply_markup: 'ReplyMarkup' = None,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
allow_sending_without_reply: bool = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
@@ -612,11 +634,11 @@ class Chat(TelegramObject):
|
||||
media: List[
|
||||
Union['InputMediaAudio', 'InputMediaDocument', 'InputMediaPhoto', 'InputMediaVideo']
|
||||
],
|
||||
disable_notification: bool = None,
|
||||
reply_to_message_id: Union[int, str] = None,
|
||||
timeout: float = 20,
|
||||
disable_notification: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: int = None,
|
||||
timeout: DVInput[float] = DEFAULT_20,
|
||||
api_kwargs: JSONDict = None,
|
||||
allow_sending_without_reply: bool = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
) -> List['Message']:
|
||||
"""Shortcut for::
|
||||
|
||||
@@ -641,7 +663,7 @@ class Chat(TelegramObject):
|
||||
def send_chat_action(
|
||||
self,
|
||||
action: str,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> bool:
|
||||
"""Shortcut for::
|
||||
@@ -668,13 +690,13 @@ class Chat(TelegramObject):
|
||||
self,
|
||||
photo: Union[FileInput, 'PhotoSize'],
|
||||
caption: str = None,
|
||||
disable_notification: bool = False,
|
||||
reply_to_message_id: Union[int, str] = None,
|
||||
disable_notification: DVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: int = None,
|
||||
reply_markup: 'ReplyMarkup' = None,
|
||||
timeout: float = 20,
|
||||
parse_mode: str = None,
|
||||
timeout: DVInput[float] = DEFAULT_20,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
allow_sending_without_reply: bool = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
caption_entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
filename: str = None,
|
||||
) -> 'Message':
|
||||
@@ -708,14 +730,14 @@ class Chat(TelegramObject):
|
||||
phone_number: str = None,
|
||||
first_name: str = None,
|
||||
last_name: str = None,
|
||||
disable_notification: bool = False,
|
||||
reply_to_message_id: Union[int, str] = None,
|
||||
disable_notification: DVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: int = None,
|
||||
reply_markup: 'ReplyMarkup' = None,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
contact: 'Contact' = None,
|
||||
vcard: str = None,
|
||||
api_kwargs: JSONDict = None,
|
||||
allow_sending_without_reply: bool = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
@@ -749,14 +771,14 @@ class Chat(TelegramObject):
|
||||
performer: str = None,
|
||||
title: str = None,
|
||||
caption: str = None,
|
||||
disable_notification: bool = False,
|
||||
reply_to_message_id: Union[int, str] = None,
|
||||
disable_notification: DVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: int = None,
|
||||
reply_markup: 'ReplyMarkup' = None,
|
||||
timeout: float = 20,
|
||||
parse_mode: str = None,
|
||||
timeout: DVInput[float] = DEFAULT_20,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
thumb: FileInput = None,
|
||||
api_kwargs: JSONDict = None,
|
||||
allow_sending_without_reply: bool = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
caption_entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
filename: str = None,
|
||||
) -> 'Message':
|
||||
@@ -794,15 +816,15 @@ class Chat(TelegramObject):
|
||||
document: Union[FileInput, 'Document'],
|
||||
filename: str = None,
|
||||
caption: str = None,
|
||||
disable_notification: bool = False,
|
||||
reply_to_message_id: Union[int, str] = None,
|
||||
disable_notification: DVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: int = None,
|
||||
reply_markup: 'ReplyMarkup' = None,
|
||||
timeout: float = 20,
|
||||
parse_mode: str = None,
|
||||
timeout: DVInput[float] = DEFAULT_20,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
thumb: FileInput = None,
|
||||
api_kwargs: JSONDict = None,
|
||||
disable_content_type_detection: bool = None,
|
||||
allow_sending_without_reply: bool = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
caption_entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
@@ -834,13 +856,13 @@ class Chat(TelegramObject):
|
||||
|
||||
def send_dice(
|
||||
self,
|
||||
disable_notification: bool = None,
|
||||
reply_to_message_id: Union[int, str] = None,
|
||||
disable_notification: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: int = None,
|
||||
reply_markup: 'ReplyMarkup' = None,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
emoji: str = None,
|
||||
api_kwargs: JSONDict = None,
|
||||
allow_sending_without_reply: bool = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
@@ -866,12 +888,12 @@ class Chat(TelegramObject):
|
||||
def send_game(
|
||||
self,
|
||||
game_short_name: str,
|
||||
disable_notification: bool = False,
|
||||
reply_to_message_id: Union[int, str] = None,
|
||||
disable_notification: DVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: int = None,
|
||||
reply_markup: 'InlineKeyboardMarkup' = None,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
allow_sending_without_reply: bool = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
@@ -912,15 +934,15 @@ class Chat(TelegramObject):
|
||||
need_email: bool = None,
|
||||
need_shipping_address: bool = None,
|
||||
is_flexible: bool = None,
|
||||
disable_notification: bool = False,
|
||||
reply_to_message_id: Union[int, str] = None,
|
||||
disable_notification: DVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: int = None,
|
||||
reply_markup: 'InlineKeyboardMarkup' = None,
|
||||
provider_data: Union[str, object] = None,
|
||||
send_phone_number_to_provider: bool = None,
|
||||
send_email_to_provider: bool = None,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
allow_sending_without_reply: bool = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
@@ -965,17 +987,17 @@ class Chat(TelegramObject):
|
||||
self,
|
||||
latitude: float = None,
|
||||
longitude: float = None,
|
||||
disable_notification: bool = False,
|
||||
reply_to_message_id: Union[int, str] = None,
|
||||
disable_notification: DVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: int = None,
|
||||
reply_markup: 'ReplyMarkup' = None,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
location: 'Location' = None,
|
||||
live_period: int = None,
|
||||
api_kwargs: JSONDict = None,
|
||||
horizontal_accuracy: float = None,
|
||||
heading: int = None,
|
||||
proximity_alert_radius: int = None,
|
||||
allow_sending_without_reply: bool = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
@@ -1012,13 +1034,13 @@ class Chat(TelegramObject):
|
||||
height: int = None,
|
||||
thumb: FileInput = None,
|
||||
caption: str = None,
|
||||
parse_mode: str = None,
|
||||
disable_notification: bool = False,
|
||||
reply_to_message_id: Union[int, str] = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
disable_notification: DVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: int = None,
|
||||
reply_markup: 'ReplyMarkup' = None,
|
||||
timeout: float = 20,
|
||||
timeout: DVInput[float] = DEFAULT_20,
|
||||
api_kwargs: JSONDict = None,
|
||||
allow_sending_without_reply: bool = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
caption_entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
filename: str = None,
|
||||
) -> 'Message':
|
||||
@@ -1054,12 +1076,12 @@ class Chat(TelegramObject):
|
||||
def send_sticker(
|
||||
self,
|
||||
sticker: Union[FileInput, 'Sticker'],
|
||||
disable_notification: bool = False,
|
||||
reply_to_message_id: Union[int, str] = None,
|
||||
disable_notification: DVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: int = None,
|
||||
reply_markup: 'ReplyMarkup' = None,
|
||||
timeout: float = 20,
|
||||
timeout: DVInput[float] = DEFAULT_20,
|
||||
api_kwargs: JSONDict = None,
|
||||
allow_sending_without_reply: bool = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
@@ -1089,16 +1111,16 @@ class Chat(TelegramObject):
|
||||
title: str = None,
|
||||
address: str = None,
|
||||
foursquare_id: str = None,
|
||||
disable_notification: bool = False,
|
||||
reply_to_message_id: Union[int, str] = None,
|
||||
disable_notification: DVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: int = None,
|
||||
reply_markup: 'ReplyMarkup' = None,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
venue: 'Venue' = None,
|
||||
foursquare_type: str = None,
|
||||
api_kwargs: JSONDict = None,
|
||||
google_place_id: str = None,
|
||||
google_place_type: str = None,
|
||||
allow_sending_without_reply: bool = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
|
||||
@@ -1134,17 +1156,17 @@ class Chat(TelegramObject):
|
||||
video: Union[FileInput, 'Video'],
|
||||
duration: int = None,
|
||||
caption: str = None,
|
||||
disable_notification: bool = False,
|
||||
reply_to_message_id: Union[int, str] = None,
|
||||
disable_notification: DVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: int = None,
|
||||
reply_markup: 'ReplyMarkup' = None,
|
||||
timeout: float = 20,
|
||||
timeout: DVInput[float] = DEFAULT_20,
|
||||
width: int = None,
|
||||
height: int = None,
|
||||
parse_mode: str = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
supports_streaming: bool = None,
|
||||
thumb: FileInput = None,
|
||||
api_kwargs: JSONDict = None,
|
||||
allow_sending_without_reply: bool = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
caption_entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
filename: str = None,
|
||||
) -> 'Message':
|
||||
@@ -1183,13 +1205,13 @@ class Chat(TelegramObject):
|
||||
video_note: Union[FileInput, 'VideoNote'],
|
||||
duration: int = None,
|
||||
length: int = None,
|
||||
disable_notification: bool = False,
|
||||
reply_to_message_id: Union[int, str] = None,
|
||||
disable_notification: DVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: int = None,
|
||||
reply_markup: 'ReplyMarkup' = None,
|
||||
timeout: float = 20,
|
||||
timeout: DVInput[float] = DEFAULT_20,
|
||||
thumb: FileInput = None,
|
||||
api_kwargs: JSONDict = None,
|
||||
allow_sending_without_reply: bool = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
filename: str = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
@@ -1222,13 +1244,13 @@ class Chat(TelegramObject):
|
||||
voice: Union[FileInput, 'Voice'],
|
||||
duration: int = None,
|
||||
caption: str = None,
|
||||
disable_notification: bool = False,
|
||||
reply_to_message_id: Union[int, str] = None,
|
||||
disable_notification: DVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: int = None,
|
||||
reply_markup: 'ReplyMarkup' = None,
|
||||
timeout: float = 20,
|
||||
parse_mode: str = None,
|
||||
timeout: DVInput[float] = DEFAULT_20,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
allow_sending_without_reply: bool = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
caption_entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
filename: str = None,
|
||||
) -> 'Message':
|
||||
@@ -1268,16 +1290,16 @@ class Chat(TelegramObject):
|
||||
allows_multiple_answers: bool = False,
|
||||
correct_option_id: int = None,
|
||||
is_closed: bool = None,
|
||||
disable_notification: bool = None,
|
||||
reply_to_message_id: Union[int, str] = None,
|
||||
disable_notification: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: int = None,
|
||||
reply_markup: 'ReplyMarkup' = None,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
explanation: str = None,
|
||||
explanation_parse_mode: Union[str, DefaultValue, None] = DEFAULT_NONE,
|
||||
explanation_parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
open_period: int = None,
|
||||
close_date: Union[int, datetime] = None,
|
||||
api_kwargs: JSONDict = None,
|
||||
allow_sending_without_reply: bool = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
explanation_entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
@@ -1315,15 +1337,15 @@ class Chat(TelegramObject):
|
||||
def send_copy(
|
||||
self,
|
||||
from_chat_id: Union[str, int],
|
||||
message_id: Union[str, int],
|
||||
message_id: int,
|
||||
caption: str = None,
|
||||
parse_mode: str = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_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,
|
||||
disable_notification: DVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: int = None,
|
||||
allow_sending_without_reply: DVInput[bool] = DEFAULT_NONE,
|
||||
reply_markup: 'ReplyMarkup' = None,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> 'MessageId':
|
||||
"""Shortcut for::
|
||||
@@ -1354,15 +1376,15 @@ class Chat(TelegramObject):
|
||||
def copy_message(
|
||||
self,
|
||||
chat_id: Union[int, str],
|
||||
message_id: Union[str, int],
|
||||
message_id: int,
|
||||
caption: str = None,
|
||||
parse_mode: str = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_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,
|
||||
disable_notification: DVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: int = None,
|
||||
allow_sending_without_reply: DVInput[bool] = DEFAULT_NONE,
|
||||
reply_markup: 'ReplyMarkup' = None,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> 'MessageId':
|
||||
"""Shortcut for::
|
||||
@@ -1389,3 +1411,106 @@ class Chat(TelegramObject):
|
||||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
def export_invite_link(
|
||||
self,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> str:
|
||||
"""Shortcut for::
|
||||
|
||||
bot.export_chat_invite_link(chat_id=update.effective_chat.id, *args, **kwargs)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.export_chat_invite_link`.
|
||||
|
||||
.. versionadded:: 13.4
|
||||
|
||||
Returns:
|
||||
:obj:`str`: New invite link on success.
|
||||
|
||||
"""
|
||||
return self.bot.export_chat_invite_link(
|
||||
chat_id=self.id, timeout=timeout, api_kwargs=api_kwargs
|
||||
)
|
||||
|
||||
def create_invite_link(
|
||||
self,
|
||||
expire_date: Union[int, datetime] = None,
|
||||
member_limit: int = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> 'ChatInviteLink':
|
||||
"""Shortcut for::
|
||||
|
||||
bot.create_chat_invite_link(chat_id=update.effective_chat.id, *args, **kwargs)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.create_chat_invite_link`.
|
||||
|
||||
.. versionadded:: 13.4
|
||||
|
||||
Returns:
|
||||
:class:`telegram.ChatInviteLink`
|
||||
|
||||
"""
|
||||
return self.bot.create_chat_invite_link(
|
||||
chat_id=self.id,
|
||||
expire_date=expire_date,
|
||||
member_limit=member_limit,
|
||||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
def edit_invite_link(
|
||||
self,
|
||||
invite_link: str,
|
||||
expire_date: Union[int, datetime] = None,
|
||||
member_limit: int = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> 'ChatInviteLink':
|
||||
"""Shortcut for::
|
||||
|
||||
bot.edit_chat_invite_link(chat_id=update.effective_chat.id, *args, **kwargs)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.edit_chat_invite_link`.
|
||||
|
||||
.. versionadded:: 13.4
|
||||
|
||||
Returns:
|
||||
:class:`telegram.ChatInviteLink`
|
||||
|
||||
"""
|
||||
return self.bot.edit_chat_invite_link(
|
||||
chat_id=self.id,
|
||||
invite_link=invite_link,
|
||||
expire_date=expire_date,
|
||||
member_limit=member_limit,
|
||||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
def revoke_invite_link(
|
||||
self,
|
||||
invite_link: str,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> 'ChatInviteLink':
|
||||
"""Shortcut for::
|
||||
|
||||
bot.revoke_chat_invite_link(chat_id=update.effective_chat.id, *args, **kwargs)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.revoke_chat_invite_link`.
|
||||
|
||||
.. versionadded:: 13.4
|
||||
|
||||
Returns:
|
||||
:class:`telegram.ChatInviteLink`
|
||||
|
||||
"""
|
||||
return self.bot.revoke_chat_invite_link(
|
||||
chat_id=self.id, invite_link=invite_link, timeout=timeout, api_kwargs=api_kwargs
|
||||
)
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
#!/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 an invite link for a chat."""
|
||||
import datetime
|
||||
from typing import TYPE_CHECKING, Any, Optional
|
||||
|
||||
from telegram import TelegramObject, User
|
||||
from telegram.utils.helpers import from_timestamp, to_timestamp
|
||||
from telegram.utils.types import JSONDict
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import Bot
|
||||
|
||||
|
||||
class ChatInviteLink(TelegramObject):
|
||||
"""This object represents an invite link for a chat.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`invite_link`, :attr:`creator`, :attr:`is_primary` and
|
||||
:attr:`is_revoked` are equal.
|
||||
|
||||
.. versionadded:: 13.4
|
||||
|
||||
Args:
|
||||
invite_link (:obj:`str`): The invite link.
|
||||
creator (:class:`telegram.User`): Creator of the link.
|
||||
is_primary (:obj:`bool`): :obj:`True`, if the link is primary.
|
||||
is_revoked (:obj:`bool`): :obj:`True`, if the link is revoked.
|
||||
expire_date (:class:`datetime.datetime`, optional): Date when the link will expire or
|
||||
has been expired.
|
||||
member_limit (:obj:`int`, optional): Maximum number of users that can be members of the
|
||||
chat simultaneously after joining the chat via this invite link; 1-99999.
|
||||
|
||||
Attributes:
|
||||
invite_link (:obj:`str`): The invite link. If the link was created by another chat
|
||||
administrator, then the second part of the link will be replaced with ``'…'``.
|
||||
creator (:class:`telegram.User`): Creator of the link.
|
||||
is_primary (:obj:`bool`): :obj:`True`, if the link is primary.
|
||||
is_revoked (:obj:`bool`): :obj:`True`, if the link is revoked.
|
||||
expire_date (:class:`datetime.datetime`): Optional. Date when the link will expire or
|
||||
has been expired.
|
||||
member_limit (:obj:`int`): Optional. Maximum number of users that can be members
|
||||
of the chat simultaneously after joining the chat via this invite link; 1-99999.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
invite_link: str,
|
||||
creator: User,
|
||||
is_primary: bool,
|
||||
is_revoked: bool,
|
||||
expire_date: datetime.datetime = None,
|
||||
member_limit: int = None,
|
||||
**_kwargs: Any,
|
||||
):
|
||||
# Required
|
||||
self.invite_link = invite_link
|
||||
self.creator = creator
|
||||
self.is_primary = is_primary
|
||||
self.is_revoked = is_revoked
|
||||
|
||||
# Optionals
|
||||
self.expire_date = expire_date
|
||||
self.member_limit = int(member_limit) if member_limit is not None else None
|
||||
|
||||
self._id_attrs = (self.invite_link, self.creator, self.is_primary, self.is_revoked)
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: 'Bot') -> Optional['ChatInviteLink']:
|
||||
data = cls.parse_data(data)
|
||||
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data['creator'] = User.de_json(data.get('creator'), bot)
|
||||
data['expire_date'] = from_timestamp(data.get('expire_date', None))
|
||||
|
||||
return cls(**data)
|
||||
|
||||
def to_dict(self) -> JSONDict:
|
||||
data = super().to_dict()
|
||||
|
||||
data['expire_date'] = to_timestamp(self.expire_date)
|
||||
|
||||
return data
|
||||
@@ -46,6 +46,18 @@ class ChatMember(TelegramObject):
|
||||
restrictions will be lifted for this user.
|
||||
can_be_edited (:obj:`bool`, optional): Administrators only. :obj:`True`, if the bot is
|
||||
allowed to edit administrator privileges of that user.
|
||||
can_manage_chat (:obj:`bool`, optional): Administrators only. :obj:`True`, if the
|
||||
administrator can access the chat event log, chat statistics, message statistics in
|
||||
channels, see channel members, see anonymous administrators in supergroups and ignore
|
||||
slow mode. Implied by any other administrator privilege.
|
||||
|
||||
.. versionadded:: 13.4
|
||||
|
||||
can_manage_voice_chats (:obj:`bool`, optional): Administrators only. :obj:`True`, if the
|
||||
administrator can manage voice chats.
|
||||
|
||||
.. versionadded:: 13.4
|
||||
|
||||
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
|
||||
@@ -87,6 +99,17 @@ class ChatMember(TelegramObject):
|
||||
for this user.
|
||||
can_be_edited (:obj:`bool`): Optional. If the bot is allowed to edit administrator
|
||||
privileges of that user.
|
||||
can_manage_chat (:obj:`bool`): Optional. If the administrator can access the chat event
|
||||
log, chat statistics, message statistics in channels, see channel members, see
|
||||
anonymous administrators in supergroups and ignore slow mode.
|
||||
|
||||
.. versionadded:: 13.4
|
||||
|
||||
can_manage_voice_chats (:obj:`bool`): Optional. if the administrator can manage
|
||||
voice chats.
|
||||
|
||||
.. versionadded:: 13.4
|
||||
|
||||
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.
|
||||
@@ -150,6 +173,8 @@ class ChatMember(TelegramObject):
|
||||
is_member: bool = None,
|
||||
custom_title: str = None,
|
||||
is_anonymous: bool = None,
|
||||
can_manage_chat: bool = None,
|
||||
can_manage_voice_chats: bool = None,
|
||||
**_kwargs: Any,
|
||||
):
|
||||
# Required
|
||||
@@ -175,6 +200,8 @@ class ChatMember(TelegramObject):
|
||||
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.can_manage_chat = can_manage_chat
|
||||
self.can_manage_voice_chats = can_manage_voice_chats
|
||||
|
||||
self._id_attrs = (self.user, self.status)
|
||||
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 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 ChatMemberUpdated."""
|
||||
import datetime
|
||||
from typing import TYPE_CHECKING, Any, Optional
|
||||
|
||||
from telegram import TelegramObject, User, Chat, ChatMember, ChatInviteLink
|
||||
from telegram.utils.helpers import from_timestamp, to_timestamp
|
||||
from telegram.utils.types import JSONDict
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import Bot
|
||||
|
||||
|
||||
class ChatMemberUpdated(TelegramObject):
|
||||
"""This object represents changes in the status of a chat member.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`chat`, :attr:`from_user`, :attr:`date`,
|
||||
:attr:`old_chat_member` and :attr:`new_chat_member` are equal.
|
||||
|
||||
.. versionadded:: 13.4
|
||||
|
||||
Note:
|
||||
In Python ``from`` is a reserved word, use ``from_user`` instead.
|
||||
|
||||
Args:
|
||||
chat (:class:`telegram.Chat`): Chat the user belongs to.
|
||||
from_user (:class:`telegram.User`): Performer of the action, which resulted in the change.
|
||||
date (:class:`datetime.datetime`): Date the change was done in Unix time. Converted to
|
||||
:class:`datetime.datetime`.
|
||||
old_chat_member (:class:`telegram.ChatMember`): Previous information about the chat member.
|
||||
new_chat_member (:class:`telegram.ChatMember`): New information about the chat member.
|
||||
invite_link (:class:`telegram.ChatInviteLink`, optional): Chat invite link, which was used
|
||||
by the user to join the chat. For joining by invite link events only.
|
||||
|
||||
Attributes:
|
||||
chat (:class:`telegram.Chat`): Chat the user belongs to.
|
||||
from_user (:class:`telegram.User`): Performer of the action, which resulted in the change.
|
||||
date (:class:`datetime.datetime`): Date the change was done in Unix time. Converted to
|
||||
:class:`datetime.datetime`.
|
||||
old_chat_member (:class:`telegram.ChatMember`): Previous information about the chat member.
|
||||
new_chat_member (:class:`telegram.ChatMember`): New information about the chat member.
|
||||
invite_link (:class:`telegram.ChatInviteLink`): Optional. Chat invite link, which was used
|
||||
by the user to join the chat.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
chat: Chat,
|
||||
from_user: User,
|
||||
date: datetime.datetime,
|
||||
old_chat_member: ChatMember,
|
||||
new_chat_member: ChatMember,
|
||||
invite_link: ChatInviteLink = None,
|
||||
**_kwargs: Any,
|
||||
):
|
||||
# Required
|
||||
self.chat = chat
|
||||
self.from_user = from_user
|
||||
self.date = date
|
||||
self.old_chat_member = old_chat_member
|
||||
self.new_chat_member = new_chat_member
|
||||
|
||||
# Optionals
|
||||
self.invite_link = invite_link
|
||||
|
||||
self._id_attrs = (
|
||||
self.chat,
|
||||
self.from_user,
|
||||
self.date,
|
||||
self.old_chat_member,
|
||||
self.new_chat_member,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: 'Bot') -> Optional['ChatMemberUpdated']:
|
||||
data = cls.parse_data(data)
|
||||
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data['chat'] = Chat.de_json(data.get('chat'), bot)
|
||||
data['from_user'] = User.de_json(data.get('from'), bot)
|
||||
data['date'] = from_timestamp(data.get('date'))
|
||||
data['old_chat_member'] = ChatMember.de_json(data.get('old_chat_member'), bot)
|
||||
data['new_chat_member'] = ChatMember.de_json(data.get('new_chat_member'), bot)
|
||||
data['invite_link'] = ChatInviteLink.de_json(data.get('invite_link'), bot)
|
||||
|
||||
return cls(**data)
|
||||
|
||||
def to_dict(self) -> JSONDict:
|
||||
data = super().to_dict()
|
||||
|
||||
# Required
|
||||
data['date'] = to_timestamp(self.date)
|
||||
|
||||
return data
|
||||
@@ -37,7 +37,7 @@ class ChosenInlineResult(TelegramObject):
|
||||
considered equal, if their :attr:`result_id` is equal.
|
||||
|
||||
Note:
|
||||
* In Python `from` is a reserved word, use `from_user` instead.
|
||||
* 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.
|
||||
|
||||
|
||||
@@ -21,6 +21,10 @@ The following constants were extracted from the
|
||||
`Telegram Bots API <https://core.telegram.org/bots/api>`_.
|
||||
|
||||
Attributes:
|
||||
BOT_API_VERSION (:obj:`str`): `5.1`. Telegram Bot API version supported by this
|
||||
version of `python-telegram-bot`. Also available as ``telegram.bot_api_version``.
|
||||
|
||||
.. versionadded:: 13.4
|
||||
MAX_MESSAGE_LENGTH (:obj:`int`): 4096
|
||||
MAX_CAPTION_LENGTH (:obj:`int`): 1024
|
||||
SUPPORTED_WEBHOOK_PORTS (List[:obj:`int`]): [443, 80, 88, 8443]
|
||||
@@ -88,8 +92,14 @@ Attributes:
|
||||
DICE_BASKETBALL (:obj:`str`): '🏀'
|
||||
DICE_FOOTBALL (:obj:`str`): '⚽'
|
||||
DICE_SLOT_MACHINE (:obj:`str`): '🎰'
|
||||
DICE_BOWLING (:obj:`str`): '🎳'
|
||||
|
||||
.. versionadded:: 13.4
|
||||
DICE_ALL_EMOJI (List[:obj:`str`]): List of all supported base emoji.
|
||||
|
||||
.. versionchanged:: 13.4
|
||||
Added :attr:`DICE_BOWLING`
|
||||
|
||||
:class:`telegram.MessageEntity`:
|
||||
|
||||
Attributes:
|
||||
@@ -136,6 +146,7 @@ Attributes:
|
||||
"""
|
||||
from typing import List
|
||||
|
||||
BOT_API_VERSION: str = '5.1'
|
||||
MAX_MESSAGE_LENGTH: int = 4096
|
||||
MAX_CAPTION_LENGTH: int = 1024
|
||||
ANONYMOUS_ADMIN_ID: int = 1087968824
|
||||
@@ -182,12 +193,14 @@ DICE_DARTS: str = '🎯'
|
||||
DICE_BASKETBALL: str = '🏀'
|
||||
DICE_FOOTBALL: str = '⚽'
|
||||
DICE_SLOT_MACHINE: str = '🎰'
|
||||
DICE_BOWLING: str = '🎳'
|
||||
DICE_ALL_EMOJI: List[str] = [
|
||||
DICE_DICE,
|
||||
DICE_DARTS,
|
||||
DICE_BASKETBALL,
|
||||
DICE_FOOTBALL,
|
||||
DICE_SLOT_MACHINE,
|
||||
DICE_BOWLING,
|
||||
]
|
||||
|
||||
MESSAGEENTITY_MENTION: str = 'mention'
|
||||
|
||||
+12
-2
@@ -45,13 +45,17 @@ class Dice(TelegramObject):
|
||||
3 indicates that the goal was missed. However, this behaviour is undocumented and might
|
||||
be changed by Telegram.
|
||||
|
||||
If :attr:`emoji` is "🎳", a value of 6 knocks all the pins, while a value of 1 means all
|
||||
the pins were 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.
|
||||
value (:obj:`int`): Value of the dice. 1-6 for dice, darts and bowling balls, 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:
|
||||
@@ -76,5 +80,11 @@ class Dice(TelegramObject):
|
||||
""":const:`telegram.constants.DICE_FOOTBALL`"""
|
||||
SLOT_MACHINE: ClassVar[str] = constants.DICE_SLOT_MACHINE
|
||||
""":const:`telegram.constants.DICE_SLOT_MACHINE`"""
|
||||
BOWLING: ClassVar[str] = constants.DICE_BOWLING
|
||||
"""
|
||||
:const:`telegram.constants.DICE_BOWLING`
|
||||
|
||||
.. versionadded:: 13.4
|
||||
"""
|
||||
ALL_EMOJI: ClassVar[List[str]] = constants.DICE_ALL_EMOJI
|
||||
""":const:`telegram.constants.DICE_ALL_EMOJI`"""
|
||||
|
||||
@@ -43,6 +43,7 @@ from .messagequeue import MessageQueue
|
||||
from .messagequeue import DelayQueue
|
||||
from .pollanswerhandler import PollAnswerHandler
|
||||
from .pollhandler import PollHandler
|
||||
from .chatmemberhandler import ChatMemberHandler
|
||||
from .defaults import Defaults
|
||||
|
||||
__all__ = (
|
||||
@@ -78,5 +79,6 @@ __all__ = (
|
||||
'PrefixHandler',
|
||||
'PollAnswerHandler',
|
||||
'PollHandler',
|
||||
'ChatMemberHandler',
|
||||
'Defaults',
|
||||
)
|
||||
|
||||
@@ -291,7 +291,7 @@ class BasePersistence(ABC):
|
||||
|
||||
@abstractmethod
|
||||
def get_user_data(self) -> DefaultDict[int, Dict[object, object]]:
|
||||
""" "Will be called by :class:`telegram.ext.Dispatcher` upon creation with a
|
||||
"""Will be called by :class:`telegram.ext.Dispatcher` upon creation with a
|
||||
persistence object. It should return the ``user_data`` if stored, or an empty
|
||||
``defaultdict(dict)``.
|
||||
|
||||
@@ -301,7 +301,7 @@ class BasePersistence(ABC):
|
||||
|
||||
@abstractmethod
|
||||
def get_chat_data(self) -> DefaultDict[int, Dict[object, object]]:
|
||||
""" "Will be called by :class:`telegram.ext.Dispatcher` upon creation with a
|
||||
"""Will be called by :class:`telegram.ext.Dispatcher` upon creation with a
|
||||
persistence object. It should return the ``chat_data`` if stored, or an empty
|
||||
``defaultdict(dict)``.
|
||||
|
||||
@@ -311,7 +311,7 @@ class BasePersistence(ABC):
|
||||
|
||||
@abstractmethod
|
||||
def get_bot_data(self) -> Dict[object, object]:
|
||||
""" "Will be called by :class:`telegram.ext.Dispatcher` upon creation with a
|
||||
"""Will be called by :class:`telegram.ext.Dispatcher` upon creation with a
|
||||
persistence object. It should return the ``bot_data`` if stored, or an empty
|
||||
:obj:`dict`.
|
||||
|
||||
@@ -321,7 +321,7 @@ class BasePersistence(ABC):
|
||||
|
||||
@abstractmethod
|
||||
def get_conversations(self, name: str) -> ConversationDict:
|
||||
""" "Will be called by :class:`telegram.ext.Dispatcher` when a
|
||||
"""Will be called by :class:`telegram.ext.Dispatcher` when a
|
||||
:class:`telegram.ext.ConversationHandler` is added if
|
||||
:attr:`telegram.ext.ConversationHandler.persistent` is :obj:`True`.
|
||||
It should return the conversations for the handler with `name` or an empty :obj:`dict`
|
||||
|
||||
@@ -118,7 +118,7 @@ class CallbackContext:
|
||||
@bot_data.setter
|
||||
def bot_data(self, value: object) -> NoReturn:
|
||||
raise AttributeError(
|
||||
"You can not assign a new value to bot_data, see " "https://git.io/fjxKe"
|
||||
"You can not assign a new value to bot_data, see https://git.io/Jt6ic"
|
||||
)
|
||||
|
||||
@property
|
||||
@@ -128,7 +128,7 @@ class CallbackContext:
|
||||
@chat_data.setter
|
||||
def chat_data(self, value: object) -> NoReturn:
|
||||
raise AttributeError(
|
||||
"You can not assign a new value to chat_data, see " "https://git.io/fjxKe"
|
||||
"You can not assign a new value to chat_data, see https://git.io/Jt6ic"
|
||||
)
|
||||
|
||||
@property
|
||||
@@ -138,7 +138,7 @@ class CallbackContext:
|
||||
@user_data.setter
|
||||
def user_data(self, value: object) -> NoReturn:
|
||||
raise AttributeError(
|
||||
"You can not assign a new value to user_data, see " "https://git.io/fjxKe"
|
||||
"You can not assign a new value to user_data, see https://git.io/Jt6ic"
|
||||
)
|
||||
|
||||
@classmethod
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2019-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 the ChatMemberHandler classes."""
|
||||
from typing import ClassVar, TypeVar, Union, Callable, TYPE_CHECKING
|
||||
|
||||
from telegram import Update
|
||||
from telegram.utils.helpers import DefaultValue, DEFAULT_FALSE
|
||||
from .handler import Handler
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram.ext import CallbackContext
|
||||
|
||||
RT = TypeVar('RT')
|
||||
|
||||
|
||||
class ChatMemberHandler(Handler[Update]):
|
||||
"""Handler class to handle Telegram updates that contain a chat member update.
|
||||
|
||||
.. versionadded:: 13.4
|
||||
|
||||
Note:
|
||||
:attr:`pass_user_data` and :attr:`pass_chat_data` determine whether a ``dict`` you
|
||||
can use to keep any data in will be sent to the :attr:`callback` function. Related to
|
||||
either the user or the chat that the update was sent in. For each update from the same user
|
||||
or in the same chat, it will be the same ``dict``.
|
||||
|
||||
Note that this is DEPRECATED, and you should use context based callbacks. See
|
||||
https://git.io/fxJuV for more info.
|
||||
|
||||
Warning:
|
||||
When setting ``run_async`` to :obj:`True`, you cannot rely on adding custom
|
||||
attributes to :class:`telegram.ext.CallbackContext`. See its docs for more info.
|
||||
|
||||
Args:
|
||||
callback (:obj:`callable`): The callback function for this handler. Will be called when
|
||||
:attr:`check_update` has determined that an update should be processed by this handler.
|
||||
Callback signature for context based API:
|
||||
|
||||
``def callback(update: Update, context: CallbackContext)``
|
||||
|
||||
The return value of the callback is usually ignored except for the special case of
|
||||
:class:`telegram.ext.ConversationHandler`.
|
||||
chat_member_types (:obj:`int`, optional): Pass one of :attr:`MY_CHAT_MEMBER`,
|
||||
:attr:`CHAT_MEMBER` or :attr:`ANY_CHAT_MEMBER` to specify if this handler should handle
|
||||
only updates with :attr:`telegram.Update.my_chat_member`,
|
||||
:attr:`telegram.Update.chat_member` or both. Defaults to :attr:`MY_CHAT_MEMBER`.
|
||||
pass_update_queue (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called
|
||||
``update_queue`` will be passed to the callback function. It will be the ``Queue``
|
||||
instance used by the :class:`telegram.ext.Updater` and :class:`telegram.ext.Dispatcher`
|
||||
that contains new updates which can be used to insert updates. Default is :obj:`False`.
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
pass_job_queue (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called
|
||||
``job_queue`` will be passed to the callback function. It will be a
|
||||
:class:`telegram.ext.JobQueue` instance created by the :class:`telegram.ext.Updater`
|
||||
which can be used to schedule new jobs. Default is :obj:`False`.
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
pass_user_data (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called
|
||||
``user_data`` will be passed to the callback function. Default is :obj:`False`.
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
pass_chat_data (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called
|
||||
``chat_data`` will be passed to the callback function. Default is :obj:`False`.
|
||||
DEPRECATED: Please switch to context based callbacks.
|
||||
run_async (:obj:`bool`): Determines whether the callback will run asynchronously.
|
||||
Defaults to :obj:`False`.
|
||||
|
||||
Attributes:
|
||||
callback (:obj:`callable`): The callback function for this handler.
|
||||
chat_member_types (:obj:`int`, optional): Specifies if this handler should handle
|
||||
only updates with :attr:`telegram.Update.my_chat_member`,
|
||||
:attr:`telegram.Update.chat_member` or both.
|
||||
pass_update_queue (:obj:`bool`): Determines whether ``update_queue`` will be
|
||||
passed to the callback function.
|
||||
pass_job_queue (:obj:`bool`): Determines whether ``job_queue`` will be passed to
|
||||
the callback function.
|
||||
pass_user_data (:obj:`bool`): Determines whether ``user_data`` will be passed to
|
||||
the callback function.
|
||||
pass_chat_data (:obj:`bool`): Determines whether ``chat_data`` will be passed to
|
||||
the callback function.
|
||||
run_async (:obj:`bool`): Determines whether the callback will run asynchronously.
|
||||
|
||||
"""
|
||||
|
||||
MY_CHAT_MEMBER: ClassVar[int] = -1
|
||||
""":obj:`int`: Used as a constant to handle only :attr:`telegram.Update.my_chat_member`."""
|
||||
CHAT_MEMBER: ClassVar[int] = 0
|
||||
""":obj:`int`: Used as a constant to handle only :attr:`telegram.Update.chat_member`."""
|
||||
ANY_CHAT_MEMBER: ClassVar[int] = 1
|
||||
""":obj:`int`: Used as a constant to handle bot :attr:`telegram.Update.my_chat_member`
|
||||
and :attr:`telegram.Update.chat_member`."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
callback: Callable[[Update, 'CallbackContext'], RT],
|
||||
chat_member_types: int = MY_CHAT_MEMBER,
|
||||
pass_update_queue: bool = False,
|
||||
pass_job_queue: bool = False,
|
||||
pass_user_data: bool = False,
|
||||
pass_chat_data: bool = False,
|
||||
run_async: Union[bool, DefaultValue] = DEFAULT_FALSE,
|
||||
):
|
||||
super().__init__(
|
||||
callback,
|
||||
pass_update_queue=pass_update_queue,
|
||||
pass_job_queue=pass_job_queue,
|
||||
pass_user_data=pass_user_data,
|
||||
pass_chat_data=pass_chat_data,
|
||||
run_async=run_async,
|
||||
)
|
||||
|
||||
self.chat_member_types = chat_member_types
|
||||
|
||||
def check_update(self, update: object) -> bool:
|
||||
"""Determines whether an update should be passed to this handlers :attr:`callback`.
|
||||
|
||||
Args:
|
||||
update (:class:`telegram.Update` | :obj:`object`): Incoming update.
|
||||
|
||||
Returns:
|
||||
:obj:`bool`
|
||||
|
||||
"""
|
||||
if isinstance(update, Update):
|
||||
if not (update.my_chat_member or update.chat_member):
|
||||
return False
|
||||
if self.chat_member_types == self.ANY_CHAT_MEMBER:
|
||||
return True
|
||||
if self.chat_member_types == self.CHAT_MEMBER:
|
||||
return bool(update.chat_member)
|
||||
return bool(update.my_chat_member)
|
||||
return False
|
||||
@@ -16,13 +16,14 @@
|
||||
#
|
||||
# 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=R0201, E0401
|
||||
# pylint: disable=R0201
|
||||
"""This module contains the class Defaults, which allows to pass default values to Updater."""
|
||||
from typing import NoReturn, Optional, Union
|
||||
from typing import NoReturn, Optional, Dict, Any
|
||||
|
||||
import pytz
|
||||
|
||||
from telegram.utils.helpers import DEFAULT_NONE, DefaultValue
|
||||
from telegram.utils.helpers import DEFAULT_NONE
|
||||
from telegram.utils.types import ODVInput
|
||||
|
||||
|
||||
class Defaults:
|
||||
@@ -47,6 +48,9 @@ class Defaults:
|
||||
appearing throughout PTB, i.e. if a timezone naive date(time) object is passed
|
||||
somewhere, it will be assumed to be in ``tzinfo``. Must be a timezone provided by the
|
||||
``pytz`` module. Defaults to UTC.
|
||||
|
||||
Note:
|
||||
Will *not* be used for :meth:`telegram.Bot.get_updates`!
|
||||
run_async (:obj:`bool`, optional): Default setting for the ``run_async`` parameter of
|
||||
handlers and error handlers registered through :meth:`Dispatcher.add_handler` and
|
||||
:meth:`Dispatcher.add_error_handler`. Defaults to :obj:`False`.
|
||||
@@ -54,6 +58,8 @@ class Defaults:
|
||||
Attributes:
|
||||
parse_mode (:obj:`str`): Optional. Send Markdown or HTML, if you want Telegram apps to show
|
||||
bold, italic, fixed-width text or URLs in your bot's message.
|
||||
explanation_parse_mode (:obj:`str`): Optional. Alias for :attr:`parse_mode`, used for
|
||||
the corresponding parameter of :meth:`telegram.Bot.send_poll`.
|
||||
disable_notification (:obj:`bool`): Optional. Sends the message silently. Users will
|
||||
receive a notification with no sound.
|
||||
disable_web_page_preview (:obj:`bool`): Optional. Disables link previews for links in this
|
||||
@@ -80,7 +86,7 @@ class Defaults:
|
||||
disable_web_page_preview: bool = None,
|
||||
# Timeout needs special treatment, since the bot methods have two different
|
||||
# default values for timeout (None and 20s)
|
||||
timeout: Union[float, DefaultValue] = DEFAULT_NONE,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
quote: bool = None,
|
||||
tzinfo: pytz.BaseTzInfo = pytz.utc,
|
||||
run_async: bool = False,
|
||||
@@ -95,6 +101,26 @@ class Defaults:
|
||||
self._tzinfo = tzinfo
|
||||
self._run_async = run_async
|
||||
|
||||
# Gather all defaults that actually have a default value
|
||||
self._api_defaults = {}
|
||||
for kwarg in (
|
||||
'parse_mode',
|
||||
'explanation_parse_mode',
|
||||
'disable_notification',
|
||||
'disable_web_page_preview',
|
||||
'allow_sending_without_reply',
|
||||
):
|
||||
value = getattr(self, kwarg)
|
||||
if value not in [None, DEFAULT_NONE]:
|
||||
self._api_defaults[kwarg] = value
|
||||
# Special casing, as None is a valid default value
|
||||
if self.timeout != DEFAULT_NONE:
|
||||
self._api_defaults['timeout'] = self.timeout
|
||||
|
||||
@property
|
||||
def api_defaults(self) -> Dict[str, Any]:
|
||||
return self._api_defaults
|
||||
|
||||
@property
|
||||
def parse_mode(self) -> Optional[str]:
|
||||
return self._parse_mode
|
||||
@@ -106,6 +132,17 @@ class Defaults:
|
||||
"not have any effect."
|
||||
)
|
||||
|
||||
@property
|
||||
def explanation_parse_mode(self) -> Optional[str]:
|
||||
return self._parse_mode
|
||||
|
||||
@explanation_parse_mode.setter
|
||||
def explanation_parse_mode(self, value: object) -> NoReturn:
|
||||
raise AttributeError(
|
||||
"You can not assign a new value to defaults after because it would "
|
||||
"not have any effect."
|
||||
)
|
||||
|
||||
@property
|
||||
def disable_notification(self) -> Optional[bool]:
|
||||
return self._disable_notification
|
||||
@@ -140,7 +177,7 @@ class Defaults:
|
||||
)
|
||||
|
||||
@property
|
||||
def timeout(self) -> Union[float, DefaultValue]:
|
||||
def timeout(self) -> ODVInput[float]:
|
||||
return self._timeout
|
||||
|
||||
@timeout.setter
|
||||
|
||||
@@ -80,7 +80,7 @@ def run_async(
|
||||
|
||||
class DispatcherHandlerStop(Exception):
|
||||
"""
|
||||
Raise this in handler to prevent execution any other handler (even in different group).
|
||||
Raise this in handler to prevent execution of any other handler (even in different group).
|
||||
|
||||
In order to use this exception in a :class:`telegram.ext.ConversationHandler`, pass the
|
||||
optional ``state`` parameter instead of returning the next state:
|
||||
@@ -619,7 +619,7 @@ class Dispatcher:
|
||||
callback (:obj:`callable`): The callback function for this error handler. Will be
|
||||
called when an error is raised. Callback signature for context based API:
|
||||
|
||||
``def callback(update: Update, context: CallbackContext)``
|
||||
``def callback(update: object, context: CallbackContext)``
|
||||
|
||||
The error that happened will be present in context.error.
|
||||
run_async (:obj:`bool`, optional): Whether this handlers callback should be run
|
||||
|
||||
+104
-31
@@ -91,7 +91,7 @@ class BaseFilter(ABC):
|
||||
|
||||
|
||||
If you want to create your own filters create a class inheriting from either
|
||||
:class:`MessageFilter` or :class:`UpdateFilter` and implement a :meth:``filter`` method that
|
||||
:class:`MessageFilter` or :class:`UpdateFilter` and implement a :meth:`filter` method that
|
||||
returns a boolean: :obj:`True` if the message should be
|
||||
handled, :obj:`False` otherwise.
|
||||
Note that the filters work only as class instances, not
|
||||
@@ -148,7 +148,8 @@ class MessageFilter(BaseFilter, ABC):
|
||||
"""Base class for all Message Filters. In contrast to :class:`UpdateFilter`, the object passed
|
||||
to :meth:`filter` is ``update.effective_message``.
|
||||
|
||||
Please see :class:`telegram.ext.BaseFilter` for details on how to create custom filters.
|
||||
Please see :class:`telegram.ext.filters.BaseFilter` for details on how to create custom
|
||||
filters.
|
||||
|
||||
Attributes:
|
||||
name (:obj:`str`): Name for this filter. Defaults to the type of filter.
|
||||
@@ -176,11 +177,12 @@ class MessageFilter(BaseFilter, ABC):
|
||||
|
||||
|
||||
class UpdateFilter(BaseFilter, ABC):
|
||||
"""Base class for all Update Filters. In contrast to :class:`UpdateFilter`, the object
|
||||
"""Base class for all Update Filters. In contrast to :class:`MessageFilter`, the object
|
||||
passed to :meth:`filter` is ``update``, which allows to create filters like
|
||||
:attr:`Filters.update.edited_message`.
|
||||
|
||||
Please see :class:`telegram.ext.BaseFilter` for details on how to create custom filters.
|
||||
Please see :class:`telegram.ext.filters.BaseFilter` for details on how to create custom
|
||||
filters.
|
||||
|
||||
Attributes:
|
||||
name (:obj:`str`): Name for this filter. Defaults to the type of filter.
|
||||
@@ -316,7 +318,7 @@ class MergedFilter(UpdateFilter):
|
||||
|
||||
class XORFilter(UpdateFilter):
|
||||
"""Convenience filter acting as wrapper for :class:`MergedFilter` representing the an XOR gate
|
||||
for two filters
|
||||
for two filters.
|
||||
|
||||
Args:
|
||||
base_filter: Filter 1 of the merged filter.
|
||||
@@ -495,7 +497,7 @@ class Filters:
|
||||
def filter(self, message: Message) -> bool:
|
||||
return bool(
|
||||
message.entities
|
||||
and any([e.type == MessageEntity.BOT_COMMAND for e in message.entities])
|
||||
and any(e.type == MessageEntity.BOT_COMMAND for e in message.entities)
|
||||
)
|
||||
|
||||
def __call__( # type: ignore[override]
|
||||
@@ -1003,6 +1005,15 @@ officedocument.wordprocessingml.document")``.
|
||||
:attr: `telegram.Message.supergroup_chat_created` or
|
||||
:attr: `telegram.Message.channel_chat_created`."""
|
||||
|
||||
class _MessageAutoDeleteTimerChanged(MessageFilter):
|
||||
name = 'MessageAutoDeleteTimerChanged'
|
||||
|
||||
def filter(self, message: Message) -> bool:
|
||||
return bool(message.message_auto_delete_timer_changed)
|
||||
|
||||
message_auto_delete_timer_changed = _MessageAutoDeleteTimerChanged()
|
||||
"""Messages that contain :attr:`message_auto_delete_timer_changed`"""
|
||||
|
||||
class _Migrate(MessageFilter):
|
||||
name = 'Filters.status_update.migrate'
|
||||
|
||||
@@ -1040,6 +1051,33 @@ officedocument.wordprocessingml.document")``.
|
||||
proximity_alert_triggered = _ProximityAlertTriggered()
|
||||
"""Messages that contain :attr:`telegram.Message.proximity_alert_triggered`."""
|
||||
|
||||
class _VoiceChatStarted(MessageFilter):
|
||||
name = 'Filters.status_update.voice_chat_started'
|
||||
|
||||
def filter(self, message: Message) -> bool:
|
||||
return bool(message.voice_chat_started)
|
||||
|
||||
voice_chat_started = _VoiceChatStarted()
|
||||
"""Messages that contain :attr:`telegram.Message.voice_chat_started`."""
|
||||
|
||||
class _VoiceChatEnded(MessageFilter):
|
||||
name = 'Filters.status_update.voice_chat_ended'
|
||||
|
||||
def filter(self, message: Message) -> bool:
|
||||
return bool(message.voice_chat_ended)
|
||||
|
||||
voice_chat_ended = _VoiceChatEnded()
|
||||
"""Messages that contain :attr:`telegram.Message.voice_chat_ended`."""
|
||||
|
||||
class _VoiceChatParticipantsInvited(MessageFilter):
|
||||
name = 'Filters.status_update.voice_chat_participants_invited'
|
||||
|
||||
def filter(self, message: Message) -> bool:
|
||||
return bool(message.voice_chat_participants_invited)
|
||||
|
||||
voice_chat_participants_invited = _VoiceChatParticipantsInvited()
|
||||
"""Messages that contain :attr:`telegram.Message.voice_chat_participants_invited`."""
|
||||
|
||||
name = 'Filters.status_update'
|
||||
|
||||
def filter(self, message: Update) -> bool:
|
||||
@@ -1050,10 +1088,14 @@ officedocument.wordprocessingml.document")``.
|
||||
or self.new_chat_photo(message)
|
||||
or self.delete_chat_photo(message)
|
||||
or self.chat_created(message)
|
||||
or self.message_auto_delete_timer_changed(message)
|
||||
or self.migrate(message)
|
||||
or self.pinned_message(message)
|
||||
or self.connected_website(message)
|
||||
or self.proximity_alert_triggered(message)
|
||||
or self.voice_chat_started(message)
|
||||
or self.voice_chat_ended(message)
|
||||
or self.voice_chat_participants_invited(message)
|
||||
)
|
||||
|
||||
status_update = _StatusUpdate()
|
||||
@@ -1075,18 +1117,35 @@ officedocument.wordprocessingml.document")``.
|
||||
left_chat_member: Messages that contain
|
||||
:attr:`telegram.Message.left_chat_member`.
|
||||
migrate: Messages that contain
|
||||
:attr:`telegram.Message.migrate_from_chat_id` or
|
||||
:attr: `telegram.Message.migrate_from_chat_id`.
|
||||
:attr:`telegram.Message.migrate_to_chat_id` or
|
||||
:attr:`telegram.Message.migrate_from_chat_id`.
|
||||
new_chat_members: Messages that contain
|
||||
:attr:`telegram.Message.new_chat_members`.
|
||||
new_chat_photo: Messages that contain
|
||||
:attr:`telegram.Message.new_chat_photo`.
|
||||
new_chat_title: Messages that contain
|
||||
:attr:`telegram.Message.new_chat_title`.
|
||||
message_auto_delete_timer_changed: Messages that contain
|
||||
:attr:`message_auto_delete_timer_changed`.
|
||||
|
||||
.. versionadded:: 13.4
|
||||
pinned_message: Messages that contain
|
||||
:attr:`telegram.Message.pinned_message`.
|
||||
proximity_alert_triggered: Messages that contain
|
||||
:attr:`telegram.Message.proximity_alert_triggered`.
|
||||
voice_chat_started: Messages that contain
|
||||
:attr:`telegram.Message.voice_chat_started`.
|
||||
|
||||
.. versionadded:: 13.4
|
||||
voice_chat_ended: Messages that contain
|
||||
:attr:`telegram.Message.voice_chat_ended`.
|
||||
|
||||
.. versionadded:: 13.4
|
||||
voice_chat_participants_invited: Messages that contain
|
||||
:attr:`telegram.Message.voice_chat_participants_invited`.
|
||||
|
||||
.. versionadded:: 13.4
|
||||
|
||||
"""
|
||||
|
||||
class _Forwarded(MessageFilter):
|
||||
@@ -1413,7 +1472,8 @@ officedocument.wordprocessingml.document")``.
|
||||
user_id(:class:`telegram.utils.types.SLT[int]`, optional):
|
||||
Which user ID(s) to allow through.
|
||||
username(:class:`telegram.utils.types.SLT[str]`, optional):
|
||||
Which username(s) to allow through. Leading '@'s in usernames will be discarded.
|
||||
Which username(s) to allow through. Leading ``'@'`` s in usernames will be
|
||||
discarded.
|
||||
allow_empty(:obj:`bool`, optional): Whether updates should be processed, if no user
|
||||
is specified in :attr:`user_ids` and :attr:`usernames`. Defaults to :obj:`False`
|
||||
|
||||
@@ -1422,8 +1482,8 @@ officedocument.wordprocessingml.document")``.
|
||||
|
||||
Attributes:
|
||||
user_ids(set(:obj:`int`), optional): Which user ID(s) to allow through.
|
||||
usernames(set(:obj:`str`), optional): Which username(s) (without leading '@') to allow
|
||||
through.
|
||||
usernames(set(:obj:`str`), optional): Which username(s) (without leading ``'@'``) to
|
||||
allow through.
|
||||
allow_empty(:obj:`bool`, optional): Whether updates should be processed, if no user
|
||||
is specified in :attr:`user_ids` and :attr:`usernames`.
|
||||
|
||||
@@ -1456,7 +1516,7 @@ officedocument.wordprocessingml.document")``.
|
||||
Args:
|
||||
username(:class:`telegram.utils.types.SLT[str]`, optional):
|
||||
Which username(s) to allow through.
|
||||
Leading '@'s in usernames will be discarded.
|
||||
Leading ``'@'`` s in usernames will be discarded.
|
||||
"""
|
||||
return super().add_usernames(username)
|
||||
|
||||
@@ -1477,7 +1537,7 @@ officedocument.wordprocessingml.document")``.
|
||||
Args:
|
||||
username(:class:`telegram.utils.types.SLT[str]`, optional):
|
||||
Which username(s) to disallow through.
|
||||
Leading '@'s in usernames will be discarded.
|
||||
Leading ``'@'`` s in usernames will be discarded.
|
||||
"""
|
||||
return super().remove_usernames(username)
|
||||
|
||||
@@ -1511,7 +1571,8 @@ officedocument.wordprocessingml.document")``.
|
||||
bot_id(:class:`telegram.utils.types.SLT[int]`, optional):
|
||||
Which bot ID(s) to allow through.
|
||||
username(:class:`telegram.utils.types.SLT[str]`, optional):
|
||||
Which username(s) to allow through. Leading '@'s in usernames will be discarded.
|
||||
Which username(s) to allow through. Leading ``'@'`` s in usernames will be
|
||||
discarded.
|
||||
allow_empty(:obj:`bool`, optional): Whether updates should be processed, if no user
|
||||
is specified in :attr:`bot_ids` and :attr:`usernames`. Defaults to :obj:`False`
|
||||
|
||||
@@ -1520,8 +1581,8 @@ officedocument.wordprocessingml.document")``.
|
||||
|
||||
Attributes:
|
||||
bot_ids(set(:obj:`int`), optional): Which bot ID(s) to allow through.
|
||||
usernames(set(:obj:`str`), optional): Which username(s) (without leading '@') to allow
|
||||
through.
|
||||
usernames(set(:obj:`str`), optional): Which username(s) (without leading ``'@'``) to
|
||||
allow through.
|
||||
allow_empty(:obj:`bool`, optional): Whether updates should be processed, if no bot
|
||||
is specified in :attr:`bot_ids` and :attr:`usernames`.
|
||||
|
||||
@@ -1554,7 +1615,7 @@ officedocument.wordprocessingml.document")``.
|
||||
Args:
|
||||
username(:class:`telegram.utils.types.SLT[str]`, optional):
|
||||
Which username(s) to allow through.
|
||||
Leading '@'s in usernames will be discarded.
|
||||
Leading ``'@'`` s in usernames will be discarded.
|
||||
"""
|
||||
return super().add_usernames(username)
|
||||
|
||||
@@ -1576,7 +1637,7 @@ officedocument.wordprocessingml.document")``.
|
||||
Args:
|
||||
username(:class:`telegram.utils.types.SLT[str]`, optional):
|
||||
Which username(s) to disallow through.
|
||||
Leading '@'s in usernames will be discarded.
|
||||
Leading ``'@'`` s in usernames will be discarded.
|
||||
"""
|
||||
return super().remove_usernames(username)
|
||||
|
||||
@@ -1610,7 +1671,7 @@ officedocument.wordprocessingml.document")``.
|
||||
Which chat ID(s) to allow through.
|
||||
username(:class:`telegram.utils.types.SLT[str]`, optional):
|
||||
Which username(s) to allow through.
|
||||
Leading `'@'` s in usernames will be discarded.
|
||||
Leading ``'@'`` s in usernames will be discarded.
|
||||
allow_empty(:obj:`bool`, optional): Whether updates should be processed, if no chat
|
||||
is specified in :attr:`chat_ids` and :attr:`usernames`. Defaults to :obj:`False`
|
||||
|
||||
@@ -1619,8 +1680,8 @@ officedocument.wordprocessingml.document")``.
|
||||
|
||||
Attributes:
|
||||
chat_ids(set(:obj:`int`), optional): Which chat ID(s) to allow through.
|
||||
usernames(set(:obj:`str`), optional): Which username(s) (without leading '@') to allow
|
||||
through.
|
||||
usernames(set(:obj:`str`), optional): Which username(s) (without leading ``'@'``) to
|
||||
allow through.
|
||||
allow_empty(:obj:`bool`, optional): Whether updates should be processed, if no chat
|
||||
is specified in :attr:`chat_ids` and :attr:`usernames`.
|
||||
|
||||
@@ -1636,7 +1697,7 @@ officedocument.wordprocessingml.document")``.
|
||||
Args:
|
||||
username(:class:`telegram.utils.types.SLT[str]`, optional):
|
||||
Which username(s) to allow through.
|
||||
Leading `'@'` s in usernames will be discarded.
|
||||
Leading ``'@'`` s in usernames will be discarded.
|
||||
"""
|
||||
return super().add_usernames(username)
|
||||
|
||||
@@ -1657,7 +1718,7 @@ officedocument.wordprocessingml.document")``.
|
||||
Args:
|
||||
username(:class:`telegram.utils.types.SLT[str]`, optional):
|
||||
Which username(s) to disallow through.
|
||||
Leading '@'s in usernames will be discarded.
|
||||
Leading ``'@'`` s in usernames will be discarded.
|
||||
"""
|
||||
return super().remove_usernames(username)
|
||||
|
||||
@@ -1677,16 +1738,22 @@ officedocument.wordprocessingml.document")``.
|
||||
username.
|
||||
|
||||
Examples:
|
||||
* To filter for messages forwarded from a channel with ID ``-1234``, use
|
||||
``MessageHandler(Filters.sender_chat(-1234), callback_method)``.
|
||||
* To filter for messages forwarded to a discussion group from a channel with ID
|
||||
``-1234``, use ``MessageHandler(Filters.sender_chat(-1234), callback_method)``.
|
||||
* To filter for messages of anonymous admins in a super group with username
|
||||
``@anonymous``, use
|
||||
``MessageHandler(Filters.sender_chat(username='anonymous'), callback_method)``.
|
||||
* To filter for messages forwarded from *any* channel, use
|
||||
* To filter for messages forwarded to a discussion group from *any* channel, use
|
||||
``MessageHandler(Filters.sender_chat.channel, callback_method)``.
|
||||
* To filter for messages of anonymous admins in *any* super group, use
|
||||
``MessageHandler(Filters.sender_chat.super_group, callback_method)``.
|
||||
|
||||
Note:
|
||||
Remember, ``sender_chat`` is also set for messages in a channel as the channel itself,
|
||||
so when your bot is an admin in a channel and the linked discussion group, you would
|
||||
receive the message twice (once from inside the channel, once inside the discussion
|
||||
group).
|
||||
|
||||
Warning:
|
||||
:attr:`chat_ids` will return a *copy* of the saved chat ids as :class:`frozenset`. This
|
||||
is to ensure thread safety. To add/remove a chat, you should use :meth:`add_usernames`,
|
||||
@@ -1700,7 +1767,7 @@ officedocument.wordprocessingml.document")``.
|
||||
Which sender chat chat ID(s) to allow through.
|
||||
username(:class:`telegram.utils.types.SLT[str]`, optional):
|
||||
Which sender chat username(s) to allow through.
|
||||
Leading `'@'` s in usernames will be discarded.
|
||||
Leading ``'@'`` s in usernames will be discarded.
|
||||
allow_empty(:obj:`bool`, optional): Whether updates should be processed, if no sender
|
||||
chat is specified in :attr:`chat_ids` and :attr:`usernames`. Defaults to
|
||||
:obj:`False`
|
||||
@@ -1711,7 +1778,7 @@ officedocument.wordprocessingml.document")``.
|
||||
Attributes:
|
||||
chat_ids(set(:obj:`int`), optional): Which sender chat chat ID(s) to allow through.
|
||||
usernames(set(:obj:`str`), optional): Which sender chat username(s) (without leading
|
||||
'@') to allow through.
|
||||
``'@'``) to allow through.
|
||||
allow_empty(:obj:`bool`, optional): Whether updates should be processed, if no sender
|
||||
chat is specified in :attr:`chat_ids` and :attr:`usernames`.
|
||||
super_group: Messages whose sender chat is a super group.
|
||||
@@ -1735,7 +1802,7 @@ officedocument.wordprocessingml.document")``.
|
||||
Args:
|
||||
username(:class:`telegram.utils.types.SLT[str]`, optional):
|
||||
Which sender chat username(s) to allow through.
|
||||
Leading `'@'` s in usernames will be discarded.
|
||||
Leading ``'@'`` s in usernames will be discarded.
|
||||
"""
|
||||
return super().add_usernames(username)
|
||||
|
||||
@@ -1756,7 +1823,7 @@ officedocument.wordprocessingml.document")``.
|
||||
Args:
|
||||
username(:class:`telegram.utils.types.SLT[str]`, optional):
|
||||
Which sender chat username(s) to disallow through.
|
||||
Leading `'@'` s in usernames will be discarded.
|
||||
Leading ``'@'`` s in usernames will be discarded.
|
||||
"""
|
||||
return super().remove_usernames(username)
|
||||
|
||||
@@ -1827,6 +1894,7 @@ officedocument.wordprocessingml.document")``.
|
||||
basketball = _DiceEmoji('🏀', 'basketball')
|
||||
football = _DiceEmoji('⚽')
|
||||
slot_machine = _DiceEmoji('🎰')
|
||||
bowling = _DiceEmoji('🎳', 'bowling')
|
||||
|
||||
dice = _Dice()
|
||||
"""Dice Messages. If an integer or a list of integers is passed, it filters messages to only
|
||||
@@ -1859,6 +1927,11 @@ officedocument.wordprocessingml.document")``.
|
||||
as for :attr:`Filters.dice`.
|
||||
slot_machine: Dice messages with the emoji 🎰. Passing a list of integers is supported just
|
||||
as for :attr:`Filters.dice`.
|
||||
bowling: Dice messages with the emoji 🎳. Passing a list of integers is supported just
|
||||
as for :attr:`Filters.dice`.
|
||||
|
||||
.. versionadded:: 13.4
|
||||
|
||||
"""
|
||||
|
||||
class language(MessageFilter):
|
||||
@@ -1892,7 +1965,7 @@ officedocument.wordprocessingml.document")``.
|
||||
"""""" # remove method from docs
|
||||
return bool(
|
||||
message.from_user.language_code
|
||||
and any([message.from_user.language_code.startswith(x) for x in self.lang])
|
||||
and any(message.from_user.language_code.startswith(x) for x in self.lang)
|
||||
)
|
||||
|
||||
class _UpdateType(UpdateFilter):
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#
|
||||
# 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
|
||||
"""This module contains the classes JobQueue and Job."""
|
||||
|
||||
import datetime
|
||||
|
||||
@@ -24,9 +24,11 @@ import functools
|
||||
import queue as q
|
||||
import threading
|
||||
import time
|
||||
import warnings
|
||||
from typing import TYPE_CHECKING, Callable, List, NoReturn
|
||||
|
||||
from telegram.ext.utils.promise import Promise
|
||||
from telegram.utils.deprecate import TelegramDeprecationWarning
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import Bot
|
||||
@@ -44,6 +46,10 @@ class DelayQueue(threading.Thread):
|
||||
Processes callbacks from queue with specified throughput limits. Creates a separate thread to
|
||||
process callbacks with delays.
|
||||
|
||||
.. deprecated:: 13.3
|
||||
:class:`telegram.ext.DelayQueue` in its current form is deprecated and will be reinvented
|
||||
in a future release. See `this thread <https://git.io/JtDbF>`_ for a list of known bugs.
|
||||
|
||||
Args:
|
||||
queue (:obj:`Queue`, optional): Used to pass callbacks to thread. Creates ``Queue``
|
||||
implicitly if not provided.
|
||||
@@ -82,6 +88,12 @@ class DelayQueue(threading.Thread):
|
||||
autostart: bool = True,
|
||||
name: str = None,
|
||||
):
|
||||
warnings.warn(
|
||||
'DelayQueue in its current form is deprecated and will be reinvented in a future '
|
||||
'release. See https://git.io/JtDbF for a list of known bugs.',
|
||||
category=TelegramDeprecationWarning,
|
||||
)
|
||||
|
||||
self._queue = queue if queue is not None else q.Queue()
|
||||
self.burst_limit = burst_limit
|
||||
self.time_limit = time_limit_ms / 1000
|
||||
@@ -182,6 +194,10 @@ class MessageQueue:
|
||||
Callables are processed through *group* ``DelayQueue``, then through *all* ``DelayQueue`` for
|
||||
group-type messages. For non-group messages, only the *all* ``DelayQueue`` is used.
|
||||
|
||||
.. deprecated:: 13.3
|
||||
:class:`telegram.ext.MessageQueue` in its current form is deprecated and will be reinvented
|
||||
in a future release. See `this thread <https://git.io/JtDbF>`_ for a list of known bugs.
|
||||
|
||||
Args:
|
||||
all_burst_limit (:obj:`int`, optional): Number of maximum *all-type* callbacks to process
|
||||
per time-window defined by :attr:`all_time_limit_ms`. Defaults to 30.
|
||||
@@ -210,6 +226,12 @@ class MessageQueue:
|
||||
exc_route: Callable[[Exception], None] = None,
|
||||
autostart: bool = True,
|
||||
):
|
||||
warnings.warn(
|
||||
'MessageQueue in its current form is deprecated and will be reinvented in a future '
|
||||
'release. See https://git.io/JtDbF for a list of known bugs.',
|
||||
category=TelegramDeprecationWarning,
|
||||
)
|
||||
|
||||
# create according delay queues, use composition
|
||||
self._all_delayq = DelayQueue(
|
||||
burst_limit=all_burst_limit,
|
||||
|
||||
+112
-61
@@ -244,36 +244,56 @@ class Updater:
|
||||
self,
|
||||
poll_interval: float = 0.0,
|
||||
timeout: float = 10,
|
||||
clean: bool = False,
|
||||
clean: bool = None,
|
||||
bootstrap_retries: int = -1,
|
||||
read_latency: float = 2.0,
|
||||
allowed_updates: List[str] = None,
|
||||
drop_pending_updates: bool = None,
|
||||
) -> Optional[Queue]:
|
||||
"""Starts polling updates from Telegram.
|
||||
|
||||
Args:
|
||||
poll_interval (:obj:`float`, optional): Time to wait between polling updates from
|
||||
Telegram in seconds. Default is 0.0.
|
||||
timeout (:obj:`float`, optional): Passed to :attr:`telegram.Bot.get_updates`.
|
||||
clean (:obj:`bool`, optional): Whether to clean any pending updates on Telegram servers
|
||||
before actually starting to poll. Default is :obj:`False`.
|
||||
timeout (:obj:`float`, optional): Passed to :meth:`telegram.Bot.get_updates`.
|
||||
drop_pending_updates (:obj:`bool`, optional): Whether to clean any pending updates on
|
||||
Telegram servers before actually starting to poll. Default is :obj:`False`.
|
||||
|
||||
.. versionadded :: 13.4
|
||||
clean (:obj:`bool`, optional): Alias for ``drop_pending_updates``.
|
||||
|
||||
.. deprecated:: 13.4
|
||||
Use ``drop_pending_updates`` instead.
|
||||
bootstrap_retries (:obj:`int`, optional): Whether the bootstrapping phase of the
|
||||
`Updater` will retry on failures on the Telegram server.
|
||||
:class:`telegram.ext.Updater` will retry on failures on the Telegram server.
|
||||
|
||||
* < 0 - retry indefinitely (default)
|
||||
* 0 - no retries
|
||||
* > 0 - retry up to X times
|
||||
|
||||
allowed_updates (List[:obj:`str`], optional): Passed to
|
||||
:attr:`telegram.Bot.get_updates`.
|
||||
:meth:`telegram.Bot.get_updates`.
|
||||
read_latency (:obj:`float` | :obj:`int`, optional): Grace time in seconds for receiving
|
||||
the reply from server. Will be added to the `timeout` value and used as the read
|
||||
the reply from server. Will be added to the ``timeout`` value and used as the read
|
||||
timeout from server (Default: 2).
|
||||
|
||||
Returns:
|
||||
:obj:`Queue`: The update queue that can be filled from the main thread.
|
||||
|
||||
"""
|
||||
if (clean is not None) and (drop_pending_updates is not None):
|
||||
raise TypeError('`clean` and `drop_pending_updates` are mutually exclusive.')
|
||||
|
||||
if clean is not None:
|
||||
warnings.warn(
|
||||
'The argument `clean` of `start_polling` is deprecated. Please use '
|
||||
'`drop_pending_updates` instead.',
|
||||
category=TelegramDeprecationWarning,
|
||||
stacklevel=2,
|
||||
)
|
||||
|
||||
drop_pending_updates = drop_pending_updates if drop_pending_updates is not None else clean
|
||||
|
||||
with self.__lock:
|
||||
if not self.running:
|
||||
self.running = True
|
||||
@@ -290,7 +310,7 @@ class Updater:
|
||||
timeout,
|
||||
read_latency,
|
||||
bootstrap_retries,
|
||||
clean,
|
||||
drop_pending_updates,
|
||||
allowed_updates,
|
||||
ready=polling_ready,
|
||||
)
|
||||
@@ -310,18 +330,20 @@ class Updater:
|
||||
url_path: str = '',
|
||||
cert: str = None,
|
||||
key: str = None,
|
||||
clean: bool = False,
|
||||
clean: bool = None,
|
||||
bootstrap_retries: int = 0,
|
||||
webhook_url: str = None,
|
||||
allowed_updates: List[str] = None,
|
||||
force_event_loop: bool = False,
|
||||
drop_pending_updates: bool = None,
|
||||
ip_address: str = None,
|
||||
) -> Optional[Queue]:
|
||||
"""
|
||||
Starts a small http server to listen for updates via webhook. If cert
|
||||
and key are not provided, the webhook will be started directly on
|
||||
http://listen:port/url_path, so SSL can be handled by another
|
||||
application. Else, the webhook will be started on
|
||||
https://listen:port/url_path
|
||||
https://listen:port/url_path. Also calls :meth:`telegram.Bot.set_webhook` as required.
|
||||
|
||||
Note:
|
||||
Due to an incompatibility of the Tornado library PTB uses for the webhook with Python
|
||||
@@ -338,19 +360,29 @@ class Updater:
|
||||
url_path (:obj:`str`, optional): Path inside url.
|
||||
cert (:obj:`str`, optional): Path to the SSL certificate file.
|
||||
key (:obj:`str`, optional): Path to the SSL key file.
|
||||
clean (:obj:`bool`, optional): Whether to clean any pending updates on Telegram servers
|
||||
before actually starting the webhook. Default is :obj:`False`.
|
||||
drop_pending_updates (:obj:`bool`, optional): Whether to clean any pending updates on
|
||||
Telegram servers before actually starting to poll. Default is :obj:`False`.
|
||||
|
||||
.. versionadded :: 13.4
|
||||
clean (:obj:`bool`, optional): Alias for ``drop_pending_updates``.
|
||||
|
||||
.. deprecated:: 13.4
|
||||
Use ``drop_pending_updates`` instead.
|
||||
bootstrap_retries (:obj:`int`, optional): Whether the bootstrapping phase of the
|
||||
`Updater` will retry on failures on the Telegram server.
|
||||
:class:`telegram.ext.Updater` will retry on failures on the Telegram server.
|
||||
|
||||
* < 0 - retry indefinitely (default)
|
||||
* 0 - no retries
|
||||
* > 0 - retry up to X times
|
||||
|
||||
webhook_url (:obj:`str`, optional): Explicitly specify the webhook url. Useful behind
|
||||
NAT, reverse proxy, etc. Default is derived from `listen`, `port` & `url_path`.
|
||||
NAT, reverse proxy, etc. Default is derived from ``listen``, ``port`` &
|
||||
``url_path``.
|
||||
ip_address (:obj:`str`, optional): Passed to :meth:`telegram.Bot.set_webhook`.
|
||||
|
||||
.. versionadded :: 13.4
|
||||
allowed_updates (List[:obj:`str`], optional): Passed to
|
||||
:attr:`telegram.Bot.set_webhook`.
|
||||
:meth:`telegram.Bot.set_webhook`.
|
||||
force_event_loop (:obj:`bool`, optional): Force using the current event loop. See above
|
||||
note for details. Defaults to :obj:`False`
|
||||
|
||||
@@ -358,6 +390,19 @@ class Updater:
|
||||
:obj:`Queue`: The update queue that can be filled from the main thread.
|
||||
|
||||
"""
|
||||
if (clean is not None) and (drop_pending_updates is not None):
|
||||
raise TypeError('`clean` and `drop_pending_updates` are mutually exclusive.')
|
||||
|
||||
if clean is not None:
|
||||
warnings.warn(
|
||||
'The argument `clean` of `start_webhook` is deprecated. Please use '
|
||||
'`drop_pending_updates` instead.',
|
||||
category=TelegramDeprecationWarning,
|
||||
stacklevel=2,
|
||||
)
|
||||
|
||||
drop_pending_updates = drop_pending_updates if drop_pending_updates is not None else clean
|
||||
|
||||
with self.__lock:
|
||||
if not self.running:
|
||||
self.running = True
|
||||
@@ -376,11 +421,12 @@ class Updater:
|
||||
cert,
|
||||
key,
|
||||
bootstrap_retries,
|
||||
clean,
|
||||
drop_pending_updates,
|
||||
webhook_url,
|
||||
allowed_updates,
|
||||
ready=webhook_ready,
|
||||
force_event_loop=force_event_loop,
|
||||
ip_address=ip_address,
|
||||
)
|
||||
|
||||
self.logger.debug('Waiting for Dispatcher and Webhook to start')
|
||||
@@ -398,7 +444,7 @@ class Updater:
|
||||
timeout,
|
||||
read_latency,
|
||||
bootstrap_retries,
|
||||
clean,
|
||||
drop_pending_updates,
|
||||
allowed_updates,
|
||||
ready=None,
|
||||
): # pragma: no cover
|
||||
@@ -408,7 +454,12 @@ class Updater:
|
||||
|
||||
self.logger.debug('Updater thread started (polling)')
|
||||
|
||||
self._bootstrap(bootstrap_retries, clean=clean, webhook_url='', allowed_updates=None)
|
||||
self._bootstrap(
|
||||
bootstrap_retries,
|
||||
drop_pending_updates=drop_pending_updates,
|
||||
webhook_url='',
|
||||
allowed_updates=None,
|
||||
)
|
||||
|
||||
self.logger.debug('Bootstrap done')
|
||||
|
||||
@@ -504,14 +555,20 @@ class Updater:
|
||||
cert,
|
||||
key,
|
||||
bootstrap_retries,
|
||||
clean,
|
||||
drop_pending_updates,
|
||||
webhook_url,
|
||||
allowed_updates,
|
||||
ready=None,
|
||||
force_event_loop=False,
|
||||
ip_address=None,
|
||||
):
|
||||
self.logger.debug('Updater thread started (webhook)')
|
||||
|
||||
# Note that we only use the SSL certificate for the WebhookServer, if the key is also
|
||||
# present. This is because the WebhookServer may not actually be in charge of performing
|
||||
# the SSL handshake, e.g. in case a reverse proxy is used
|
||||
use_ssl = cert is not None and key is not None
|
||||
|
||||
if not url_path.startswith('/'):
|
||||
url_path = f'/{url_path}'
|
||||
|
||||
@@ -532,23 +589,18 @@ class Updater:
|
||||
# Create and start server
|
||||
self.httpd = WebhookServer(listen, port, app, ssl_ctx)
|
||||
|
||||
if use_ssl:
|
||||
# DO NOT CHANGE: Only set webhook if SSL is handled by library
|
||||
if not webhook_url:
|
||||
webhook_url = self._gen_webhook_url(listen, port, url_path)
|
||||
if not webhook_url:
|
||||
webhook_url = self._gen_webhook_url(listen, port, url_path)
|
||||
|
||||
self._bootstrap(
|
||||
max_retries=bootstrap_retries,
|
||||
clean=clean,
|
||||
webhook_url=webhook_url,
|
||||
cert=open(cert, 'rb'),
|
||||
allowed_updates=allowed_updates,
|
||||
)
|
||||
elif clean:
|
||||
self.logger.warning(
|
||||
"cleaning updates is not supported if "
|
||||
"SSL-termination happens elsewhere; skipping"
|
||||
)
|
||||
# We pass along the cert to the webhook if present.
|
||||
self._bootstrap(
|
||||
max_retries=bootstrap_retries,
|
||||
drop_pending_updates=drop_pending_updates,
|
||||
webhook_url=webhook_url,
|
||||
allowed_updates=allowed_updates,
|
||||
cert=open(cert, 'rb') if cert is not None else None,
|
||||
ip_address=ip_address,
|
||||
)
|
||||
|
||||
self.httpd.serve_forever(force_event_loop=force_event_loop, ready=ready)
|
||||
|
||||
@@ -558,24 +610,34 @@ class Updater:
|
||||
|
||||
@no_type_check
|
||||
def _bootstrap(
|
||||
self, max_retries, clean, webhook_url, allowed_updates, cert=None, bootstrap_interval=5
|
||||
self,
|
||||
max_retries,
|
||||
drop_pending_updates,
|
||||
webhook_url,
|
||||
allowed_updates,
|
||||
cert=None,
|
||||
bootstrap_interval=5,
|
||||
ip_address=None,
|
||||
):
|
||||
retries = [0]
|
||||
|
||||
def bootstrap_del_webhook():
|
||||
self.bot.delete_webhook()
|
||||
return False
|
||||
|
||||
def bootstrap_clean_updates():
|
||||
self.logger.debug('Cleaning updates from Telegram server')
|
||||
updates = self.bot.get_updates()
|
||||
while updates:
|
||||
updates = self.bot.get_updates(updates[-1].update_id + 1)
|
||||
self.logger.debug('Deleting webhook')
|
||||
if drop_pending_updates:
|
||||
self.logger.debug('Dropping pending updates from Telegram server')
|
||||
self.bot.delete_webhook(drop_pending_updates=drop_pending_updates)
|
||||
return False
|
||||
|
||||
def bootstrap_set_webhook():
|
||||
self.logger.debug('Setting webhook')
|
||||
if drop_pending_updates:
|
||||
self.logger.debug('Dropping pending updates from Telegram server')
|
||||
self.bot.set_webhook(
|
||||
url=webhook_url, certificate=cert, allowed_updates=allowed_updates
|
||||
url=webhook_url,
|
||||
certificate=cert,
|
||||
allowed_updates=allowed_updates,
|
||||
ip_address=ip_address,
|
||||
drop_pending_updates=drop_pending_updates,
|
||||
)
|
||||
return False
|
||||
|
||||
@@ -589,11 +651,11 @@ class Updater:
|
||||
self.logger.error('Failed bootstrap phase after %s retries (%s)', retries[0], exc)
|
||||
raise exc
|
||||
|
||||
# Cleaning pending messages is done by polling for them - so we need to delete webhook if
|
||||
# one is configured.
|
||||
# We also take this chance to delete pre-configured webhook if this is a polling Updater.
|
||||
# NOTE: We don't know ahead if a webhook is configured, so we just delete.
|
||||
if clean or not webhook_url:
|
||||
# Dropping pending updates from TG can be efficiently done with the drop_pending_updates
|
||||
# parameter of delete/start_webhook, even in the case of polling. Also we want to make
|
||||
# sure that no webhook is configured in case of polling, so we just always call
|
||||
# delete_webhook for polling
|
||||
if drop_pending_updates or not webhook_url:
|
||||
self._network_loop_retry(
|
||||
bootstrap_del_webhook,
|
||||
bootstrap_onerr_cb,
|
||||
@@ -602,17 +664,6 @@ class Updater:
|
||||
)
|
||||
retries[0] = 0
|
||||
|
||||
# Clean pending messages, if requested.
|
||||
if clean:
|
||||
self._network_loop_retry(
|
||||
bootstrap_clean_updates,
|
||||
bootstrap_onerr_cb,
|
||||
'bootstrap clean updates',
|
||||
bootstrap_interval,
|
||||
)
|
||||
retries[0] = 0
|
||||
sleep(1)
|
||||
|
||||
# Restore/set webhook settings, if needed. Again, we don't know ahead if a webhook is set,
|
||||
# so we set it anyhow.
|
||||
if webhook_url:
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#
|
||||
# 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
|
||||
# pylint: disable=C0114
|
||||
|
||||
import asyncio
|
||||
import logging
|
||||
@@ -95,7 +95,7 @@ class WebhookServer:
|
||||
not force_event_loop
|
||||
and os.name == 'nt'
|
||||
and sys.version_info >= (3, 8)
|
||||
and isinstance(loop, asyncio.ProactorEventLoop)
|
||||
and isinstance(loop, asyncio.ProactorEventLoop) # type: ignore[attr-defined]
|
||||
):
|
||||
raise TypeError(
|
||||
'`ProactorEventLoop` is incompatible with '
|
||||
@@ -123,7 +123,7 @@ class WebhookServer:
|
||||
and (
|
||||
isinstance(
|
||||
asyncio.get_event_loop_policy(),
|
||||
asyncio.WindowsProactorEventLoopPolicy, # pylint: disable=E1101
|
||||
asyncio.WindowsProactorEventLoopPolicy, # type: ignore # pylint: disable
|
||||
)
|
||||
)
|
||||
): # pylint: disable=E1101
|
||||
@@ -140,7 +140,7 @@ class WebhookAppClass(tornado.web.Application):
|
||||
def __init__(self, webhook_path: str, bot: 'Bot', update_queue: Queue):
|
||||
self.shared_objects = {"bot": bot, "update_queue": update_queue}
|
||||
handlers = [(rf"{webhook_path}/?", WebhookHandler, self.shared_objects)] # noqa
|
||||
tornado.web.Application.__init__(self, handlers)
|
||||
tornado.web.Application.__init__(self, handlers) # type: ignore
|
||||
|
||||
def log_request(self, handler: tornado.web.RequestHandler) -> None:
|
||||
pass
|
||||
@@ -149,7 +149,7 @@ class WebhookAppClass(tornado.web.Application):
|
||||
# WebhookHandler, process webhook calls
|
||||
# pylint: disable=W0223
|
||||
class WebhookHandler(tornado.web.RequestHandler):
|
||||
SUPPORTED_METHODS = ["POST"]
|
||||
SUPPORTED_METHODS = ["POST"] # type: ignore
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
|
||||
@@ -20,7 +20,8 @@
|
||||
from typing import TYPE_CHECKING, Any, Optional
|
||||
|
||||
from telegram import PhotoSize, TelegramObject
|
||||
from telegram.utils.types import JSONDict
|
||||
from telegram.utils.helpers import DEFAULT_NONE
|
||||
from telegram.utils.types import JSONDict, ODVInput
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import Bot, File
|
||||
@@ -104,7 +105,9 @@ class Animation(TelegramObject):
|
||||
|
||||
return cls(bot=bot, **data)
|
||||
|
||||
def get_file(self, timeout: float = None, api_kwargs: JSONDict = None) -> 'File':
|
||||
def get_file(
|
||||
self, timeout: ODVInput[float] = DEFAULT_NONE, api_kwargs: JSONDict = None
|
||||
) -> 'File':
|
||||
"""Convenience wrapper over :attr:`telegram.Bot.get_file`
|
||||
|
||||
For the documentation of the arguments, please see :meth:`telegram.Bot.get_file`.
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
from typing import TYPE_CHECKING, Any, Optional
|
||||
|
||||
from telegram import PhotoSize, TelegramObject
|
||||
from telegram.utils.types import JSONDict
|
||||
from telegram.utils.helpers import DEFAULT_NONE
|
||||
from telegram.utils.types import JSONDict, ODVInput
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import Bot, File
|
||||
@@ -108,7 +109,9 @@ class Audio(TelegramObject):
|
||||
|
||||
return cls(bot=bot, **data)
|
||||
|
||||
def get_file(self, timeout: float = None, api_kwargs: JSONDict = None) -> 'File':
|
||||
def get_file(
|
||||
self, timeout: ODVInput[float] = DEFAULT_NONE, api_kwargs: JSONDict = None
|
||||
) -> 'File':
|
||||
"""Convenience wrapper over :attr:`telegram.Bot.get_file`
|
||||
|
||||
For the documentation of the arguments, please see :meth:`telegram.Bot.get_file`.
|
||||
|
||||
@@ -20,7 +20,8 @@
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from telegram import TelegramObject
|
||||
from telegram.utils.types import JSONDict
|
||||
from telegram.utils.helpers import DEFAULT_NONE
|
||||
from telegram.utils.types import JSONDict, ODVInput
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import Bot, File
|
||||
@@ -85,7 +86,9 @@ class ChatPhoto(TelegramObject):
|
||||
self.big_file_unique_id,
|
||||
)
|
||||
|
||||
def get_small_file(self, timeout: float = None, api_kwargs: JSONDict = None) -> 'File':
|
||||
def get_small_file(
|
||||
self, timeout: ODVInput[float] = DEFAULT_NONE, api_kwargs: JSONDict = None
|
||||
) -> 'File':
|
||||
"""Convenience wrapper over :attr:`telegram.Bot.get_file` for getting the
|
||||
small (160x160) chat photo
|
||||
|
||||
@@ -102,7 +105,9 @@ class ChatPhoto(TelegramObject):
|
||||
file_id=self.small_file_id, timeout=timeout, api_kwargs=api_kwargs
|
||||
)
|
||||
|
||||
def get_big_file(self, timeout: float = None, api_kwargs: JSONDict = None) -> 'File':
|
||||
def get_big_file(
|
||||
self, timeout: ODVInput[float] = DEFAULT_NONE, api_kwargs: JSONDict = None
|
||||
) -> 'File':
|
||||
"""Convenience wrapper over :attr:`telegram.Bot.get_file` for getting the
|
||||
big (640x640) chat photo
|
||||
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
from typing import TYPE_CHECKING, Any, Optional
|
||||
|
||||
from telegram import PhotoSize, TelegramObject
|
||||
from telegram.utils.types import JSONDict
|
||||
from telegram.utils.helpers import DEFAULT_NONE
|
||||
from telegram.utils.types import JSONDict, ODVInput
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import Bot, File
|
||||
@@ -95,7 +96,9 @@ class Document(TelegramObject):
|
||||
|
||||
return cls(bot=bot, **data)
|
||||
|
||||
def get_file(self, timeout: float = None, api_kwargs: JSONDict = None) -> 'File':
|
||||
def get_file(
|
||||
self, timeout: ODVInput[float] = DEFAULT_NONE, api_kwargs: JSONDict = None
|
||||
) -> 'File':
|
||||
"""Convenience wrapper over :attr:`telegram.Bot.get_file`
|
||||
|
||||
For the documentation of the arguments, please see :meth:`telegram.Bot.get_file`.
|
||||
|
||||
@@ -30,8 +30,8 @@ from telegram import (
|
||||
Video,
|
||||
MessageEntity,
|
||||
)
|
||||
from telegram.utils.helpers import DEFAULT_NONE, DefaultValue, parse_file_input
|
||||
from telegram.utils.types import FileInput, JSONDict
|
||||
from telegram.utils.helpers import DEFAULT_NONE, parse_file_input
|
||||
from telegram.utils.types import FileInput, JSONDict, ODVInput
|
||||
|
||||
|
||||
class InputMedia(TelegramObject):
|
||||
@@ -117,7 +117,7 @@ class InputMediaAnimation(InputMedia):
|
||||
media: Union[FileInput, Animation],
|
||||
thumb: FileInput = None,
|
||||
caption: str = None,
|
||||
parse_mode: Union[str, DefaultValue] = DEFAULT_NONE,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
width: int = None,
|
||||
height: int = None,
|
||||
duration: int = None,
|
||||
@@ -188,7 +188,7 @@ class InputMediaPhoto(InputMedia):
|
||||
self,
|
||||
media: Union[FileInput, PhotoSize],
|
||||
caption: str = None,
|
||||
parse_mode: Union[str, DefaultValue] = DEFAULT_NONE,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Union[List[MessageEntity], Tuple[MessageEntity, ...]] = None,
|
||||
filename: str = None,
|
||||
):
|
||||
@@ -272,7 +272,7 @@ class InputMediaVideo(InputMedia):
|
||||
height: int = None,
|
||||
duration: int = None,
|
||||
supports_streaming: bool = None,
|
||||
parse_mode: Union[str, DefaultValue] = DEFAULT_NONE,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
thumb: FileInput = None,
|
||||
caption_entities: Union[List[MessageEntity], Tuple[MessageEntity, ...]] = None,
|
||||
filename: str = None,
|
||||
@@ -368,7 +368,7 @@ class InputMediaAudio(InputMedia):
|
||||
media: Union[FileInput, Audio],
|
||||
thumb: FileInput = None,
|
||||
caption: str = None,
|
||||
parse_mode: Union[str, DefaultValue] = DEFAULT_NONE,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
duration: int = None,
|
||||
performer: str = None,
|
||||
title: str = None,
|
||||
@@ -456,7 +456,7 @@ class InputMediaDocument(InputMedia):
|
||||
media: Union[FileInput, Document],
|
||||
thumb: FileInput = None,
|
||||
caption: str = None,
|
||||
parse_mode: Union[str, DefaultValue] = DEFAULT_NONE,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
disable_content_type_detection: bool = None,
|
||||
caption_entities: Union[List[MessageEntity], Tuple[MessageEntity, ...]] = None,
|
||||
filename: str = None,
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from telegram import TelegramObject
|
||||
from telegram.utils.types import JSONDict
|
||||
from telegram.utils.helpers import DEFAULT_NONE
|
||||
from telegram.utils.types import JSONDict, ODVInput
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import Bot, File
|
||||
@@ -78,7 +79,9 @@ class PhotoSize(TelegramObject):
|
||||
|
||||
self._id_attrs = (self.file_unique_id,)
|
||||
|
||||
def get_file(self, timeout: float = None, api_kwargs: JSONDict = None) -> 'File':
|
||||
def get_file(
|
||||
self, timeout: ODVInput[float] = DEFAULT_NONE, api_kwargs: JSONDict = None
|
||||
) -> 'File':
|
||||
"""Convenience wrapper over :attr:`telegram.Bot.get_file`
|
||||
|
||||
For the documentation of the arguments, please see :meth:`telegram.Bot.get_file`.
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
from typing import TYPE_CHECKING, Any, List, Optional, ClassVar
|
||||
|
||||
from telegram import PhotoSize, TelegramObject, constants
|
||||
from telegram.utils.types import JSONDict
|
||||
from telegram.utils.helpers import DEFAULT_NONE
|
||||
from telegram.utils.types import JSONDict, ODVInput
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import Bot, File
|
||||
@@ -115,7 +116,9 @@ class Sticker(TelegramObject):
|
||||
|
||||
return cls(bot=bot, **data)
|
||||
|
||||
def get_file(self, timeout: float = None, api_kwargs: JSONDict = None) -> 'File':
|
||||
def get_file(
|
||||
self, timeout: ODVInput[float] = DEFAULT_NONE, api_kwargs: JSONDict = None
|
||||
) -> 'File':
|
||||
"""Convenience wrapper over :attr:`telegram.Bot.get_file`
|
||||
|
||||
For the documentation of the arguments, please see :meth:`telegram.Bot.get_file`.
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
from typing import TYPE_CHECKING, Any, Optional
|
||||
|
||||
from telegram import PhotoSize, TelegramObject
|
||||
from telegram.utils.types import JSONDict
|
||||
from telegram.utils.helpers import DEFAULT_NONE
|
||||
from telegram.utils.types import JSONDict, ODVInput
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import Bot, File
|
||||
@@ -105,7 +106,9 @@ class Video(TelegramObject):
|
||||
|
||||
return cls(bot=bot, **data)
|
||||
|
||||
def get_file(self, timeout: float = None, api_kwargs: JSONDict = None) -> 'File':
|
||||
def get_file(
|
||||
self, timeout: ODVInput[float] = DEFAULT_NONE, api_kwargs: JSONDict = None
|
||||
) -> 'File':
|
||||
"""Convenience wrapper over :attr:`telegram.Bot.get_file`
|
||||
|
||||
For the documentation of the arguments, please see :meth:`telegram.Bot.get_file`.
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
from typing import TYPE_CHECKING, Optional, Any
|
||||
|
||||
from telegram import PhotoSize, TelegramObject
|
||||
from telegram.utils.types import JSONDict
|
||||
from telegram.utils.helpers import DEFAULT_NONE
|
||||
from telegram.utils.types import JSONDict, ODVInput
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import Bot, File
|
||||
@@ -94,7 +95,9 @@ class VideoNote(TelegramObject):
|
||||
|
||||
return cls(bot=bot, **data)
|
||||
|
||||
def get_file(self, timeout: float = None, api_kwargs: JSONDict = None) -> 'File':
|
||||
def get_file(
|
||||
self, timeout: ODVInput[float] = DEFAULT_NONE, api_kwargs: JSONDict = None
|
||||
) -> 'File':
|
||||
"""Convenience wrapper over :attr:`telegram.Bot.get_file`
|
||||
|
||||
For the documentation of the arguments, please see :meth:`telegram.Bot.get_file`.
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from telegram import TelegramObject
|
||||
from telegram.utils.types import JSONDict
|
||||
from telegram.utils.helpers import DEFAULT_NONE
|
||||
from telegram.utils.types import JSONDict, ODVInput
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import Bot, File
|
||||
@@ -78,7 +79,9 @@ class Voice(TelegramObject):
|
||||
|
||||
self._id_attrs = (self.file_unique_id,)
|
||||
|
||||
def get_file(self, timeout: float = None, api_kwargs: JSONDict = None) -> 'File':
|
||||
def get_file(
|
||||
self, timeout: ODVInput[float] = DEFAULT_NONE, api_kwargs: JSONDict = None
|
||||
) -> 'File':
|
||||
"""Convenience wrapper over :attr:`telegram.Bot.get_file`
|
||||
|
||||
For the documentation of the arguments, please see :meth:`telegram.Bot.get_file`.
|
||||
|
||||
@@ -19,10 +19,11 @@
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram InlineQuery."""
|
||||
|
||||
from typing import TYPE_CHECKING, Any, Optional, List, Union, Callable, ClassVar
|
||||
from typing import TYPE_CHECKING, Any, Optional, Union, Callable, ClassVar, Sequence
|
||||
|
||||
from telegram import Location, TelegramObject, User, constants
|
||||
from telegram.utils.types import JSONDict
|
||||
from telegram.utils.helpers import DEFAULT_NONE
|
||||
from telegram.utils.types import JSONDict, ODVInput
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import Bot, InlineQueryResult
|
||||
@@ -37,7 +38,7 @@ class InlineQuery(TelegramObject):
|
||||
considered equal, if their :attr:`id` is equal.
|
||||
|
||||
Note:
|
||||
* In Python `from` is a reserved word, use `from_user` instead.
|
||||
* In Python ``from`` is a reserved word, use ``from_user`` instead.
|
||||
|
||||
Args:
|
||||
id (:obj:`str`): Unique identifier for this query.
|
||||
@@ -96,14 +97,14 @@ class InlineQuery(TelegramObject):
|
||||
def answer(
|
||||
self,
|
||||
results: Union[
|
||||
List['InlineQueryResult'], Callable[[int], Optional[List['InlineQueryResult']]]
|
||||
Sequence['InlineQueryResult'], Callable[[int], Optional[Sequence['InlineQueryResult']]]
|
||||
],
|
||||
cache_time: int = 300,
|
||||
is_personal: bool = None,
|
||||
next_offset: str = None,
|
||||
switch_pm_text: str = None,
|
||||
switch_pm_parameter: str = None,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
current_offset: str = None,
|
||||
api_kwargs: JSONDict = None,
|
||||
auto_pagination: bool = False,
|
||||
@@ -120,11 +121,11 @@ class InlineQuery(TelegramObject):
|
||||
|
||||
Args:
|
||||
auto_pagination (:obj:`bool`, optional): If set to :obj:`True`, :attr:`offset` will be
|
||||
passed as :attr:`current_offset` to :meth:telegram.Bot.answer_inline_query`.
|
||||
passed as :attr:`current_offset` to :meth:`telegram.Bot.answer_inline_query`.
|
||||
Defaults to :obj:`False`.
|
||||
|
||||
Raises:
|
||||
TypeError: If both :attr:`current_offset` and `auto_pagination` are supplied.
|
||||
TypeError: If both :attr:`current_offset` and :attr:`auto_pagination` are supplied.
|
||||
"""
|
||||
if current_offset and auto_pagination:
|
||||
# We raise TypeError instead of ValueError for backwards compatibility with versions
|
||||
|
||||
@@ -31,6 +31,10 @@ class InlineQueryResult(TelegramObject):
|
||||
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:
|
||||
All URLs passed in inline query results will be available to end users and therefore must
|
||||
be assumed to be public.
|
||||
|
||||
Args:
|
||||
type (:obj:`str`): Type of the result.
|
||||
id (:obj:`str`): Unique identifier for this result, 1-64 Bytes.
|
||||
@@ -49,14 +53,6 @@ class InlineQueryResult(TelegramObject):
|
||||
|
||||
self._id_attrs = (self.id,)
|
||||
|
||||
@property
|
||||
def _has_parse_mode(self) -> bool:
|
||||
return hasattr(self, 'parse_mode')
|
||||
|
||||
@property
|
||||
def _has_input_message_content(self) -> bool:
|
||||
return hasattr(self, 'input_message_content')
|
||||
|
||||
def to_dict(self) -> JSONDict:
|
||||
data = super().to_dict()
|
||||
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
from typing import TYPE_CHECKING, Any, Union, Tuple, List
|
||||
|
||||
from telegram import InlineQueryResult, MessageEntity
|
||||
from telegram.utils.helpers import DEFAULT_NONE, DefaultValue
|
||||
from telegram.utils.helpers import DEFAULT_NONE
|
||||
from telegram.utils.types import ODVInput
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import InputMessageContent, ReplyMarkup
|
||||
@@ -83,7 +84,7 @@ class InlineQueryResultAudio(InlineQueryResult):
|
||||
caption: str = None,
|
||||
reply_markup: 'ReplyMarkup' = None,
|
||||
input_message_content: 'InputMessageContent' = None,
|
||||
parse_mode: Union[str, DefaultValue] = DEFAULT_NONE,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Union[Tuple[MessageEntity, ...], List[MessageEntity]] = None,
|
||||
**_kwargs: Any,
|
||||
):
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
from typing import TYPE_CHECKING, Any, Union, Tuple, List
|
||||
|
||||
from telegram import InlineQueryResult, MessageEntity
|
||||
from telegram.utils.helpers import DEFAULT_NONE, DefaultValue
|
||||
from telegram.utils.helpers import DEFAULT_NONE
|
||||
from telegram.utils.types import ODVInput
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import InputMessageContent, ReplyMarkup
|
||||
@@ -74,7 +75,7 @@ class InlineQueryResultCachedAudio(InlineQueryResult):
|
||||
caption: str = None,
|
||||
reply_markup: 'ReplyMarkup' = None,
|
||||
input_message_content: 'InputMessageContent' = None,
|
||||
parse_mode: Union[str, DefaultValue] = DEFAULT_NONE,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Union[Tuple[MessageEntity, ...], List[MessageEntity]] = None,
|
||||
**_kwargs: Any,
|
||||
):
|
||||
|
||||
@@ -22,7 +22,8 @@
|
||||
from typing import TYPE_CHECKING, Any, Union, Tuple, List
|
||||
|
||||
from telegram import InlineQueryResult, MessageEntity
|
||||
from telegram.utils.helpers import DEFAULT_NONE, DefaultValue
|
||||
from telegram.utils.helpers import DEFAULT_NONE
|
||||
from telegram.utils.types import ODVInput
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import InputMessageContent, ReplyMarkup
|
||||
@@ -83,7 +84,7 @@ class InlineQueryResultCachedDocument(InlineQueryResult):
|
||||
caption: str = None,
|
||||
reply_markup: 'ReplyMarkup' = None,
|
||||
input_message_content: 'InputMessageContent' = None,
|
||||
parse_mode: Union[str, DefaultValue] = DEFAULT_NONE,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Union[Tuple[MessageEntity, ...], List[MessageEntity]] = None,
|
||||
**_kwargs: Any,
|
||||
):
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
from typing import TYPE_CHECKING, Any, Union, Tuple, List
|
||||
|
||||
from telegram import InlineQueryResult, MessageEntity
|
||||
from telegram.utils.helpers import DEFAULT_NONE, DefaultValue
|
||||
from telegram.utils.helpers import DEFAULT_NONE
|
||||
from telegram.utils.types import ODVInput
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import InputMessageContent, ReplyMarkup
|
||||
@@ -80,7 +81,7 @@ class InlineQueryResultCachedGif(InlineQueryResult):
|
||||
caption: str = None,
|
||||
reply_markup: 'ReplyMarkup' = None,
|
||||
input_message_content: 'InputMessageContent' = None,
|
||||
parse_mode: Union[str, DefaultValue] = DEFAULT_NONE,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Union[Tuple[MessageEntity, ...], List[MessageEntity]] = None,
|
||||
**_kwargs: Any,
|
||||
):
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
from typing import TYPE_CHECKING, Any, Union, Tuple, List
|
||||
|
||||
from telegram import InlineQueryResult, MessageEntity
|
||||
from telegram.utils.helpers import DEFAULT_NONE, DefaultValue
|
||||
from telegram.utils.helpers import DEFAULT_NONE
|
||||
from telegram.utils.types import ODVInput
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import InputMessageContent, ReplyMarkup
|
||||
@@ -80,7 +81,7 @@ class InlineQueryResultCachedMpeg4Gif(InlineQueryResult):
|
||||
caption: str = None,
|
||||
reply_markup: 'ReplyMarkup' = None,
|
||||
input_message_content: 'InputMessageContent' = None,
|
||||
parse_mode: Union[str, DefaultValue] = DEFAULT_NONE,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Union[Tuple[MessageEntity, ...], List[MessageEntity]] = None,
|
||||
**_kwargs: Any,
|
||||
):
|
||||
|
||||
@@ -22,7 +22,8 @@
|
||||
from typing import TYPE_CHECKING, Any, Union, Tuple, List
|
||||
|
||||
from telegram import InlineQueryResult, MessageEntity
|
||||
from telegram.utils.helpers import DEFAULT_NONE, DefaultValue
|
||||
from telegram.utils.helpers import DEFAULT_NONE
|
||||
from telegram.utils.types import ODVInput
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import InputMessageContent, ReplyMarkup
|
||||
@@ -84,7 +85,7 @@ class InlineQueryResultCachedPhoto(InlineQueryResult):
|
||||
caption: str = None,
|
||||
reply_markup: 'ReplyMarkup' = None,
|
||||
input_message_content: 'InputMessageContent' = None,
|
||||
parse_mode: Union[str, DefaultValue] = DEFAULT_NONE,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Union[Tuple[MessageEntity, ...], List[MessageEntity]] = None,
|
||||
**_kwargs: Any,
|
||||
):
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
from typing import TYPE_CHECKING, Any, Union, Tuple, List
|
||||
|
||||
from telegram import InlineQueryResult, MessageEntity
|
||||
from telegram.utils.helpers import DEFAULT_NONE, DefaultValue
|
||||
from telegram.utils.helpers import DEFAULT_NONE
|
||||
from telegram.utils.types import ODVInput
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import InputMessageContent, ReplyMarkup
|
||||
@@ -83,7 +84,7 @@ class InlineQueryResultCachedVideo(InlineQueryResult):
|
||||
caption: str = None,
|
||||
reply_markup: 'ReplyMarkup' = None,
|
||||
input_message_content: 'InputMessageContent' = None,
|
||||
parse_mode: Union[str, DefaultValue] = DEFAULT_NONE,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Union[Tuple[MessageEntity, ...], List[MessageEntity]] = None,
|
||||
**_kwargs: Any,
|
||||
):
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
from typing import TYPE_CHECKING, Any, Union, Tuple, List
|
||||
|
||||
from telegram import InlineQueryResult, MessageEntity
|
||||
from telegram.utils.helpers import DEFAULT_NONE, DefaultValue
|
||||
from telegram.utils.helpers import DEFAULT_NONE
|
||||
from telegram.utils.types import ODVInput
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import InputMessageContent, ReplyMarkup
|
||||
@@ -77,7 +78,7 @@ class InlineQueryResultCachedVoice(InlineQueryResult):
|
||||
caption: str = None,
|
||||
reply_markup: 'ReplyMarkup' = None,
|
||||
input_message_content: 'InputMessageContent' = None,
|
||||
parse_mode: Union[str, DefaultValue] = DEFAULT_NONE,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Union[Tuple[MessageEntity, ...], List[MessageEntity]] = None,
|
||||
**_kwargs: Any,
|
||||
):
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
from typing import TYPE_CHECKING, Any, Union, Tuple, List
|
||||
|
||||
from telegram import InlineQueryResult, MessageEntity
|
||||
from telegram.utils.helpers import DEFAULT_NONE, DefaultValue
|
||||
from telegram.utils.helpers import DEFAULT_NONE
|
||||
from telegram.utils.types import ODVInput
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import InputMessageContent, ReplyMarkup
|
||||
@@ -97,7 +98,7 @@ class InlineQueryResultDocument(InlineQueryResult):
|
||||
thumb_url: str = None,
|
||||
thumb_width: int = None,
|
||||
thumb_height: int = None,
|
||||
parse_mode: Union[str, DefaultValue] = DEFAULT_NONE,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Union[Tuple[MessageEntity, ...], List[MessageEntity]] = None,
|
||||
**_kwargs: Any,
|
||||
):
|
||||
|
||||
@@ -22,7 +22,8 @@
|
||||
from typing import TYPE_CHECKING, Any, Union, Tuple, List
|
||||
|
||||
from telegram import InlineQueryResult, MessageEntity
|
||||
from telegram.utils.helpers import DEFAULT_NONE, DefaultValue
|
||||
from telegram.utils.helpers import DEFAULT_NONE
|
||||
from telegram.utils.types import ODVInput
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import InputMessageContent, ReplyMarkup
|
||||
@@ -97,7 +98,7 @@ class InlineQueryResultGif(InlineQueryResult):
|
||||
reply_markup: 'ReplyMarkup' = None,
|
||||
input_message_content: 'InputMessageContent' = None,
|
||||
gif_duration: int = None,
|
||||
parse_mode: Union[str, DefaultValue] = DEFAULT_NONE,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
thumb_mime_type: str = None,
|
||||
caption_entities: Union[Tuple[MessageEntity, ...], List[MessageEntity]] = None,
|
||||
**_kwargs: Any,
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
from typing import TYPE_CHECKING, Any, Union, Tuple, List
|
||||
|
||||
from telegram import InlineQueryResult, MessageEntity
|
||||
from telegram.utils.helpers import DEFAULT_NONE, DefaultValue
|
||||
from telegram.utils.helpers import DEFAULT_NONE
|
||||
from telegram.utils.types import ODVInput
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import InputMessageContent, ReplyMarkup
|
||||
@@ -96,7 +97,7 @@ class InlineQueryResultMpeg4Gif(InlineQueryResult):
|
||||
reply_markup: 'ReplyMarkup' = None,
|
||||
input_message_content: 'InputMessageContent' = None,
|
||||
mpeg4_duration: int = None,
|
||||
parse_mode: Union[str, DefaultValue] = DEFAULT_NONE,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
thumb_mime_type: str = None,
|
||||
caption_entities: Union[Tuple[MessageEntity, ...], List[MessageEntity]] = None,
|
||||
**_kwargs: Any,
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
from typing import TYPE_CHECKING, Any, Union, Tuple, List
|
||||
|
||||
from telegram import InlineQueryResult, MessageEntity
|
||||
from telegram.utils.helpers import DEFAULT_NONE, DefaultValue
|
||||
from telegram.utils.helpers import DEFAULT_NONE
|
||||
from telegram.utils.types import ODVInput
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import InputMessageContent, ReplyMarkup
|
||||
@@ -93,7 +94,7 @@ class InlineQueryResultPhoto(InlineQueryResult):
|
||||
caption: str = None,
|
||||
reply_markup: 'ReplyMarkup' = None,
|
||||
input_message_content: 'InputMessageContent' = None,
|
||||
parse_mode: Union[str, DefaultValue] = DEFAULT_NONE,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Union[Tuple[MessageEntity, ...], List[MessageEntity]] = None,
|
||||
**_kwargs: Any,
|
||||
):
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
from typing import TYPE_CHECKING, Any, Union, Tuple, List
|
||||
|
||||
from telegram import InlineQueryResult, MessageEntity
|
||||
from telegram.utils.helpers import DEFAULT_NONE, DefaultValue
|
||||
from telegram.utils.helpers import DEFAULT_NONE
|
||||
from telegram.utils.types import ODVInput
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import InputMessageContent, ReplyMarkup
|
||||
@@ -105,7 +106,7 @@ class InlineQueryResultVideo(InlineQueryResult):
|
||||
description: str = None,
|
||||
reply_markup: 'ReplyMarkup' = None,
|
||||
input_message_content: 'InputMessageContent' = None,
|
||||
parse_mode: Union[str, DefaultValue] = DEFAULT_NONE,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Union[Tuple[MessageEntity, ...], List[MessageEntity]] = None,
|
||||
**_kwargs: Any,
|
||||
):
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
from typing import TYPE_CHECKING, Any, Union, Tuple, List
|
||||
|
||||
from telegram import InlineQueryResult, MessageEntity
|
||||
from telegram.utils.helpers import DEFAULT_NONE, DefaultValue
|
||||
from telegram.utils.helpers import DEFAULT_NONE
|
||||
from telegram.utils.types import ODVInput
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import InputMessageContent, ReplyMarkup
|
||||
@@ -81,7 +82,7 @@ class InlineQueryResultVoice(InlineQueryResult):
|
||||
caption: str = None,
|
||||
reply_markup: 'ReplyMarkup' = None,
|
||||
input_message_content: 'InputMessageContent' = None,
|
||||
parse_mode: Union[str, DefaultValue] = DEFAULT_NONE,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Union[Tuple[MessageEntity, ...], List[MessageEntity]] = None,
|
||||
**_kwargs: Any,
|
||||
):
|
||||
|
||||
@@ -29,11 +29,3 @@ class InputMessageContent(TelegramObject):
|
||||
:class:`telegram.InputVenueMessageContent` for more details.
|
||||
|
||||
"""
|
||||
|
||||
@property
|
||||
def _has_parse_mode(self) -> bool:
|
||||
return hasattr(self, 'parse_mode')
|
||||
|
||||
@property
|
||||
def _has_disable_web_page_preview(self) -> bool:
|
||||
return hasattr(self, 'disable_web_page_preview')
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
from typing import Any, Union, Tuple, List
|
||||
|
||||
from telegram import InputMessageContent, MessageEntity
|
||||
from telegram.utils.helpers import DEFAULT_NONE, DefaultValue
|
||||
from telegram.utils.types import JSONDict
|
||||
from telegram.utils.helpers import DEFAULT_NONE
|
||||
from telegram.utils.types import JSONDict, ODVInput
|
||||
|
||||
|
||||
class InputTextMessageContent(InputMessageContent):
|
||||
@@ -62,8 +62,8 @@ class InputTextMessageContent(InputMessageContent):
|
||||
def __init__(
|
||||
self,
|
||||
message_text: str,
|
||||
parse_mode: Union[str, DefaultValue] = DEFAULT_NONE,
|
||||
disable_web_page_preview: Union[bool, DefaultValue] = DEFAULT_NONE,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
disable_web_page_preview: ODVInput[bool] = DEFAULT_NONE,
|
||||
entities: Union[Tuple[MessageEntity, ...], List[MessageEntity]] = None,
|
||||
**_kwargs: Any,
|
||||
):
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
from typing import Any
|
||||
|
||||
from telegram import TelegramObject
|
||||
from telegram import TelegramObject, KeyboardButtonPollType
|
||||
|
||||
|
||||
class KeyboardButton(TelegramObject):
|
||||
@@ -63,7 +63,7 @@ class KeyboardButton(TelegramObject):
|
||||
text: str,
|
||||
request_contact: bool = None,
|
||||
request_location: bool = None,
|
||||
request_poll: bool = None,
|
||||
request_poll: KeyboardButtonPollType = None,
|
||||
**_kwargs: Any,
|
||||
):
|
||||
# Required
|
||||
|
||||
+182
-129
@@ -47,17 +47,21 @@ from telegram import (
|
||||
Video,
|
||||
VideoNote,
|
||||
Voice,
|
||||
VoiceChatStarted,
|
||||
VoiceChatEnded,
|
||||
VoiceChatParticipantsInvited,
|
||||
ProximityAlertTriggered,
|
||||
ReplyMarkup,
|
||||
MessageAutoDeleteTimerChanged,
|
||||
)
|
||||
from telegram.utils.helpers import (
|
||||
escape_markdown,
|
||||
from_timestamp,
|
||||
to_timestamp,
|
||||
DEFAULT_NONE,
|
||||
DefaultValue,
|
||||
DEFAULT_20,
|
||||
)
|
||||
from telegram.utils.types import JSONDict, FileInput
|
||||
from telegram.utils.types import JSONDict, FileInput, ODVInput, DVInput
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import (
|
||||
@@ -83,7 +87,7 @@ class Message(TelegramObject):
|
||||
considered equal, if their :attr:`message_id` and :attr:`chat` are equal.
|
||||
|
||||
Note:
|
||||
In Python `from` is a reserved word, use `from_user` instead.
|
||||
In Python ``from`` is a reserved word, use ``from_user`` instead.
|
||||
|
||||
Args:
|
||||
message_id (:obj:`int`): Unique message identifier inside this chat.
|
||||
@@ -165,6 +169,10 @@ class Message(TelegramObject):
|
||||
created. This field can't be received in a message coming through updates, because bot
|
||||
can't be a member of a channel when it is created. It can only be found in
|
||||
:attr:`reply_to_message` if someone replies to a very first message in a channel.
|
||||
message_auto_delete_timer_changed (:class:`telegram.MessageAutoDeleteTimerChanged`, \
|
||||
optional): Service message: auto-delete timer settings changed in the chat.
|
||||
|
||||
.. versionadded:: 13.4
|
||||
migrate_to_chat_id (:obj:`int`, optional): The group has been migrated to a supergroup with
|
||||
the specified identifier. This number may be greater than 32 bits and some programming
|
||||
languages may have difficulty/silent defects in interpreting it. But it is smaller than
|
||||
@@ -196,6 +204,18 @@ class Message(TelegramObject):
|
||||
proximity_alert_triggered (:class:`telegram.ProximityAlertTriggered`, optional): Service
|
||||
message. A user in the chat triggered another user's proximity alert while sharing
|
||||
Live Location.
|
||||
voice_chat_started (:class:`telegram.VoiceChatStarted`, optional): Service message: voice
|
||||
chat started.
|
||||
|
||||
.. versionadded:: 13.4
|
||||
voice_chat_ended (:class:`telegram.VoiceChatEnded`, optional): Service message: voice chat
|
||||
ended.
|
||||
|
||||
.. versionadded:: 13.4
|
||||
voice_chat_participants_invited (:class:`telegram.VoiceChatParticipantsInvited` optional):
|
||||
Service message: new participants invited to a voice chat.
|
||||
|
||||
.. versionadded:: 13.4
|
||||
reply_markup (:class:`telegram.InlineKeyboardMarkup`, optional): Inline keyboard attached
|
||||
to the message. ``login_url`` buttons are represented as ordinary url buttons.
|
||||
bot (:class:`telegram.Bot`, optional): The Bot to use for instance methods.
|
||||
@@ -257,6 +277,10 @@ class Message(TelegramObject):
|
||||
group_chat_created (:obj:`bool`): Optional. The group has been created.
|
||||
supergroup_chat_created (:obj:`bool`): Optional. The supergroup has been created.
|
||||
channel_chat_created (:obj:`bool`): Optional. The channel has been created.
|
||||
message_auto_delete_timer_changed (:class:`telegram.MessageAutoDeleteTimerChanged`):
|
||||
Optional. Service message: auto-delete timer settings changed in the chat.
|
||||
|
||||
.. versionadded:: 13.4
|
||||
migrate_to_chat_id (:obj:`int`): Optional. The group has been migrated to a supergroup with
|
||||
the specified identifier.
|
||||
migrate_from_chat_id (:obj:`int`): Optional. The supergroup has been migrated from a group
|
||||
@@ -281,6 +305,18 @@ class Message(TelegramObject):
|
||||
proximity_alert_triggered (:class:`telegram.ProximityAlertTriggered`): Optional. Service
|
||||
message. A user in the chat triggered another user's proximity alert while sharing
|
||||
Live Location.
|
||||
voice_chat_started (:class:`telegram.VoiceChatStarted`): Optional. Service message: voice
|
||||
chat started
|
||||
|
||||
.. versionadded:: 13.4
|
||||
voice_chat_ended (:class:`telegram.VoiceChatEnded`): Optional. Service message: voice chat
|
||||
ended.
|
||||
|
||||
.. versionadded:: 13.4
|
||||
voice_chat_participants_invited (:class:`telegram.VoiceChatParticipantsInvited`): Optional.
|
||||
Service message: new participants invited to a voice chat.
|
||||
|
||||
.. versionadded:: 13.4
|
||||
reply_markup (:class:`telegram.InlineKeyboardMarkup`): Optional. Inline keyboard attached
|
||||
to the message.
|
||||
bot (:class:`telegram.Bot`): Optional. The Bot to use for instance methods.
|
||||
@@ -316,6 +352,7 @@ class Message(TelegramObject):
|
||||
'group_chat_created',
|
||||
'supergroup_chat_created',
|
||||
'channel_chat_created',
|
||||
'message_auto_delete_timer_changed',
|
||||
'migrate_to_chat_id',
|
||||
'migrate_from_chat_id',
|
||||
'pinned_message',
|
||||
@@ -323,6 +360,9 @@ class Message(TelegramObject):
|
||||
'dice',
|
||||
'passport_data',
|
||||
'proximity_alert_triggered',
|
||||
'voice_chat_started',
|
||||
'voice_chat_ended',
|
||||
'voice_chat_participants_invited',
|
||||
] + ATTACHMENT_TYPES
|
||||
|
||||
def __init__(
|
||||
@@ -379,6 +419,10 @@ class Message(TelegramObject):
|
||||
via_bot: User = None,
|
||||
proximity_alert_triggered: ProximityAlertTriggered = None,
|
||||
sender_chat: Chat = None,
|
||||
voice_chat_started: VoiceChatStarted = None,
|
||||
voice_chat_ended: VoiceChatEnded = None,
|
||||
voice_chat_participants_invited: VoiceChatParticipantsInvited = None,
|
||||
message_auto_delete_timer_changed: MessageAutoDeleteTimerChanged = None,
|
||||
**_kwargs: Any,
|
||||
):
|
||||
# Required
|
||||
@@ -418,6 +462,7 @@ class Message(TelegramObject):
|
||||
self.migrate_to_chat_id = migrate_to_chat_id
|
||||
self.migrate_from_chat_id = migrate_from_chat_id
|
||||
self.channel_chat_created = bool(channel_chat_created)
|
||||
self.message_auto_delete_timer_changed = message_auto_delete_timer_changed
|
||||
self.pinned_message = pinned_message
|
||||
self.forward_from_message_id = forward_from_message_id
|
||||
self.invoice = invoice
|
||||
@@ -433,6 +478,9 @@ class Message(TelegramObject):
|
||||
self.dice = dice
|
||||
self.via_bot = via_bot
|
||||
self.proximity_alert_triggered = proximity_alert_triggered
|
||||
self.voice_chat_started = voice_chat_started
|
||||
self.voice_chat_ended = voice_chat_ended
|
||||
self.voice_chat_participants_invited = voice_chat_participants_invited
|
||||
self.reply_markup = reply_markup
|
||||
self.bot = bot
|
||||
|
||||
@@ -489,6 +537,9 @@ class Message(TelegramObject):
|
||||
data['new_chat_members'] = User.de_list(data.get('new_chat_members'), bot)
|
||||
data['left_chat_member'] = User.de_json(data.get('left_chat_member'), bot)
|
||||
data['new_chat_photo'] = PhotoSize.de_list(data.get('new_chat_photo'), bot)
|
||||
data['message_auto_delete_timer_changed'] = MessageAutoDeleteTimerChanged.de_json(
|
||||
data.get('message_auto_delete_timer_changed'), bot
|
||||
)
|
||||
data['pinned_message'] = Message.de_json(data.get('pinned_message'), bot)
|
||||
data['invoice'] = Invoice.de_json(data.get('invoice'), bot)
|
||||
data['successful_payment'] = SuccessfulPayment.de_json(data.get('successful_payment'), bot)
|
||||
@@ -500,7 +551,11 @@ class Message(TelegramObject):
|
||||
data.get('proximity_alert_triggered'), bot
|
||||
)
|
||||
data['reply_markup'] = InlineKeyboardMarkup.de_json(data.get('reply_markup'), bot)
|
||||
|
||||
data['voice_chat_started'] = VoiceChatStarted.de_json(data.get('voice_chat_started'), bot)
|
||||
data['voice_chat_ended'] = VoiceChatEnded.de_json(data.get('voice_chat_ended'), bot)
|
||||
data['voice_chat_participants_invited'] = VoiceChatParticipantsInvited.de_json(
|
||||
data.get('voice_chat_participants_invited'), bot
|
||||
)
|
||||
return cls(bot=bot, **data)
|
||||
|
||||
@property
|
||||
@@ -581,9 +636,7 @@ class Message(TelegramObject):
|
||||
|
||||
return data
|
||||
|
||||
def _quote(
|
||||
self, quote: Optional[bool], reply_to_message_id: Optional[Union[int, str]]
|
||||
) -> Optional[Union[int, str]]:
|
||||
def _quote(self, quote: Optional[bool], reply_to_message_id: Optional[int]) -> Optional[int]:
|
||||
"""Modify kwargs for replying with or without quoting."""
|
||||
if reply_to_message_id is not None:
|
||||
return reply_to_message_id
|
||||
@@ -605,14 +658,14 @@ class Message(TelegramObject):
|
||||
def reply_text(
|
||||
self,
|
||||
text: str,
|
||||
parse_mode: str = None,
|
||||
disable_web_page_preview: bool = None,
|
||||
disable_notification: bool = False,
|
||||
reply_to_message_id: Union[int, str] = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
disable_web_page_preview: ODVInput[bool] = DEFAULT_NONE,
|
||||
disable_notification: DVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: int = None,
|
||||
reply_markup: ReplyMarkup = None,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
allow_sending_without_reply: bool = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
quote: bool = None,
|
||||
) -> 'Message':
|
||||
@@ -650,13 +703,13 @@ class Message(TelegramObject):
|
||||
def reply_markdown(
|
||||
self,
|
||||
text: str,
|
||||
disable_web_page_preview: bool = None,
|
||||
disable_notification: bool = False,
|
||||
reply_to_message_id: Union[int, str] = None,
|
||||
disable_web_page_preview: ODVInput[bool] = DEFAULT_NONE,
|
||||
disable_notification: DVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: int = None,
|
||||
reply_markup: ReplyMarkup = None,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
allow_sending_without_reply: bool = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
quote: bool = None,
|
||||
) -> 'Message':
|
||||
@@ -704,13 +757,13 @@ class Message(TelegramObject):
|
||||
def reply_markdown_v2(
|
||||
self,
|
||||
text: str,
|
||||
disable_web_page_preview: bool = None,
|
||||
disable_notification: bool = False,
|
||||
reply_to_message_id: Union[int, str] = None,
|
||||
disable_web_page_preview: ODVInput[bool] = DEFAULT_NONE,
|
||||
disable_notification: DVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: int = None,
|
||||
reply_markup: ReplyMarkup = None,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
allow_sending_without_reply: bool = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
quote: bool = None,
|
||||
) -> 'Message':
|
||||
@@ -754,13 +807,13 @@ class Message(TelegramObject):
|
||||
def reply_html(
|
||||
self,
|
||||
text: str,
|
||||
disable_web_page_preview: bool = None,
|
||||
disable_notification: bool = False,
|
||||
reply_to_message_id: Union[int, str] = None,
|
||||
disable_web_page_preview: ODVInput[bool] = DEFAULT_NONE,
|
||||
disable_notification: DVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: int = None,
|
||||
reply_markup: ReplyMarkup = None,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
allow_sending_without_reply: bool = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
quote: bool = None,
|
||||
) -> 'Message':
|
||||
@@ -806,11 +859,11 @@ class Message(TelegramObject):
|
||||
media: List[
|
||||
Union['InputMediaAudio', 'InputMediaDocument', 'InputMediaPhoto', 'InputMediaVideo']
|
||||
],
|
||||
disable_notification: bool = None,
|
||||
reply_to_message_id: Union[int, str] = None,
|
||||
timeout: float = 20,
|
||||
disable_notification: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: int = None,
|
||||
timeout: DVInput[float] = DEFAULT_20,
|
||||
api_kwargs: JSONDict = None,
|
||||
allow_sending_without_reply: bool = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
quote: bool = None,
|
||||
) -> List['Message']:
|
||||
"""Shortcut for::
|
||||
@@ -846,13 +899,13 @@ class Message(TelegramObject):
|
||||
self,
|
||||
photo: Union[FileInput, 'PhotoSize'],
|
||||
caption: str = None,
|
||||
disable_notification: bool = False,
|
||||
reply_to_message_id: Union[int, str] = None,
|
||||
disable_notification: DVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: int = None,
|
||||
reply_markup: ReplyMarkup = None,
|
||||
timeout: float = 20,
|
||||
parse_mode: str = None,
|
||||
timeout: DVInput[float] = DEFAULT_20,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
allow_sending_without_reply: bool = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
caption_entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
filename: str = None,
|
||||
quote: bool = None,
|
||||
@@ -896,14 +949,14 @@ class Message(TelegramObject):
|
||||
performer: str = None,
|
||||
title: str = None,
|
||||
caption: str = None,
|
||||
disable_notification: bool = False,
|
||||
reply_to_message_id: Union[int, str] = None,
|
||||
disable_notification: DVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: int = None,
|
||||
reply_markup: ReplyMarkup = None,
|
||||
timeout: float = 20,
|
||||
parse_mode: str = None,
|
||||
timeout: DVInput[float] = DEFAULT_20,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
thumb: FileInput = None,
|
||||
api_kwargs: JSONDict = None,
|
||||
allow_sending_without_reply: bool = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
caption_entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
filename: str = None,
|
||||
quote: bool = None,
|
||||
@@ -949,15 +1002,15 @@ class Message(TelegramObject):
|
||||
document: Union[FileInput, 'Document'],
|
||||
filename: str = None,
|
||||
caption: str = None,
|
||||
disable_notification: bool = False,
|
||||
reply_to_message_id: Union[int, str] = None,
|
||||
disable_notification: DVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: int = None,
|
||||
reply_markup: ReplyMarkup = None,
|
||||
timeout: float = 20,
|
||||
parse_mode: str = None,
|
||||
timeout: DVInput[float] = DEFAULT_20,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
thumb: FileInput = None,
|
||||
api_kwargs: JSONDict = None,
|
||||
disable_content_type_detection: bool = None,
|
||||
allow_sending_without_reply: bool = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
caption_entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
quote: bool = None,
|
||||
) -> 'Message':
|
||||
@@ -1003,13 +1056,13 @@ class Message(TelegramObject):
|
||||
height: int = None,
|
||||
thumb: FileInput = None,
|
||||
caption: str = None,
|
||||
parse_mode: str = None,
|
||||
disable_notification: bool = False,
|
||||
reply_to_message_id: Union[int, str] = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
disable_notification: DVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: int = None,
|
||||
reply_markup: ReplyMarkup = None,
|
||||
timeout: float = 20,
|
||||
timeout: DVInput[float] = DEFAULT_20,
|
||||
api_kwargs: JSONDict = None,
|
||||
allow_sending_without_reply: bool = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
caption_entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
filename: str = None,
|
||||
quote: bool = None,
|
||||
@@ -1053,12 +1106,12 @@ class Message(TelegramObject):
|
||||
def reply_sticker(
|
||||
self,
|
||||
sticker: Union[FileInput, 'Sticker'],
|
||||
disable_notification: bool = False,
|
||||
reply_to_message_id: Union[int, str] = None,
|
||||
disable_notification: DVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: int = None,
|
||||
reply_markup: ReplyMarkup = None,
|
||||
timeout: float = 20,
|
||||
timeout: DVInput[float] = DEFAULT_20,
|
||||
api_kwargs: JSONDict = None,
|
||||
allow_sending_without_reply: bool = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
quote: bool = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
@@ -1094,17 +1147,17 @@ class Message(TelegramObject):
|
||||
video: Union[FileInput, 'Video'],
|
||||
duration: int = None,
|
||||
caption: str = None,
|
||||
disable_notification: bool = False,
|
||||
reply_to_message_id: Union[int, str] = None,
|
||||
disable_notification: DVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: int = None,
|
||||
reply_markup: ReplyMarkup = None,
|
||||
timeout: float = 20,
|
||||
timeout: DVInput[float] = DEFAULT_20,
|
||||
width: int = None,
|
||||
height: int = None,
|
||||
parse_mode: str = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
supports_streaming: bool = None,
|
||||
thumb: FileInput = None,
|
||||
api_kwargs: JSONDict = None,
|
||||
allow_sending_without_reply: bool = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
caption_entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
filename: str = None,
|
||||
quote: bool = None,
|
||||
@@ -1151,13 +1204,13 @@ class Message(TelegramObject):
|
||||
video_note: Union[FileInput, 'VideoNote'],
|
||||
duration: int = None,
|
||||
length: int = None,
|
||||
disable_notification: bool = False,
|
||||
reply_to_message_id: Union[int, str] = None,
|
||||
disable_notification: DVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: int = None,
|
||||
reply_markup: ReplyMarkup = None,
|
||||
timeout: float = 20,
|
||||
timeout: DVInput[float] = DEFAULT_20,
|
||||
thumb: FileInput = None,
|
||||
api_kwargs: JSONDict = None,
|
||||
allow_sending_without_reply: bool = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
filename: str = None,
|
||||
quote: bool = None,
|
||||
) -> 'Message':
|
||||
@@ -1198,13 +1251,13 @@ class Message(TelegramObject):
|
||||
voice: Union[FileInput, 'Voice'],
|
||||
duration: int = None,
|
||||
caption: str = None,
|
||||
disable_notification: bool = False,
|
||||
reply_to_message_id: Union[int, str] = None,
|
||||
disable_notification: DVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: int = None,
|
||||
reply_markup: ReplyMarkup = None,
|
||||
timeout: float = 20,
|
||||
parse_mode: str = None,
|
||||
timeout: DVInput[float] = DEFAULT_20,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
allow_sending_without_reply: bool = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
caption_entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
filename: str = None,
|
||||
quote: bool = None,
|
||||
@@ -1246,17 +1299,17 @@ class Message(TelegramObject):
|
||||
self,
|
||||
latitude: float = None,
|
||||
longitude: float = None,
|
||||
disable_notification: bool = False,
|
||||
reply_to_message_id: Union[int, str] = None,
|
||||
disable_notification: DVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: int = None,
|
||||
reply_markup: ReplyMarkup = None,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
location: Location = None,
|
||||
live_period: int = None,
|
||||
api_kwargs: JSONDict = None,
|
||||
horizontal_accuracy: float = None,
|
||||
heading: int = None,
|
||||
proximity_alert_radius: int = None,
|
||||
allow_sending_without_reply: bool = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
quote: bool = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
@@ -1300,16 +1353,16 @@ class Message(TelegramObject):
|
||||
title: str = None,
|
||||
address: str = None,
|
||||
foursquare_id: str = None,
|
||||
disable_notification: bool = False,
|
||||
reply_to_message_id: Union[int, str] = None,
|
||||
disable_notification: DVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: int = None,
|
||||
reply_markup: ReplyMarkup = None,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
venue: Venue = None,
|
||||
foursquare_type: str = None,
|
||||
api_kwargs: JSONDict = None,
|
||||
google_place_id: str = None,
|
||||
google_place_type: str = None,
|
||||
allow_sending_without_reply: bool = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
quote: bool = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
@@ -1353,14 +1406,14 @@ class Message(TelegramObject):
|
||||
phone_number: str = None,
|
||||
first_name: str = None,
|
||||
last_name: str = None,
|
||||
disable_notification: bool = False,
|
||||
reply_to_message_id: Union[int, str] = None,
|
||||
disable_notification: DVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: int = None,
|
||||
reply_markup: ReplyMarkup = None,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
contact: Contact = None,
|
||||
vcard: str = None,
|
||||
api_kwargs: JSONDict = None,
|
||||
allow_sending_without_reply: bool = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
quote: bool = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
@@ -1404,16 +1457,16 @@ class Message(TelegramObject):
|
||||
allows_multiple_answers: bool = False,
|
||||
correct_option_id: int = None,
|
||||
is_closed: bool = None,
|
||||
disable_notification: bool = None,
|
||||
reply_to_message_id: Union[int, str] = None,
|
||||
disable_notification: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: int = None,
|
||||
reply_markup: ReplyMarkup = None,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
explanation: str = None,
|
||||
explanation_parse_mode: Union[str, DefaultValue, None] = DEFAULT_NONE,
|
||||
explanation_parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
open_period: int = None,
|
||||
close_date: Union[int, datetime.datetime] = None,
|
||||
api_kwargs: JSONDict = None,
|
||||
allow_sending_without_reply: bool = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
explanation_entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
quote: bool = None,
|
||||
) -> 'Message':
|
||||
@@ -1458,13 +1511,13 @@ class Message(TelegramObject):
|
||||
|
||||
def reply_dice(
|
||||
self,
|
||||
disable_notification: bool = None,
|
||||
reply_to_message_id: Union[int, str] = None,
|
||||
disable_notification: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: int = None,
|
||||
reply_markup: ReplyMarkup = None,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
emoji: str = None,
|
||||
api_kwargs: JSONDict = None,
|
||||
allow_sending_without_reply: bool = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
quote: bool = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
@@ -1498,7 +1551,7 @@ class Message(TelegramObject):
|
||||
def reply_chat_action(
|
||||
self,
|
||||
action: str,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> bool:
|
||||
"""Shortcut for::
|
||||
@@ -1523,12 +1576,12 @@ class Message(TelegramObject):
|
||||
def reply_game(
|
||||
self,
|
||||
game_short_name: str,
|
||||
disable_notification: bool = False,
|
||||
reply_to_message_id: Union[int, str] = None,
|
||||
disable_notification: DVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: int = None,
|
||||
reply_markup: 'InlineKeyboardMarkup' = None,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
allow_sending_without_reply: bool = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
quote: bool = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
@@ -1579,15 +1632,15 @@ class Message(TelegramObject):
|
||||
need_email: bool = None,
|
||||
need_shipping_address: bool = None,
|
||||
is_flexible: bool = None,
|
||||
disable_notification: bool = False,
|
||||
reply_to_message_id: Union[int, str] = None,
|
||||
disable_notification: DVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: int = None,
|
||||
reply_markup: 'InlineKeyboardMarkup' = None,
|
||||
provider_data: Union[str, object] = None,
|
||||
send_phone_number_to_provider: bool = None,
|
||||
send_email_to_provider: bool = None,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
allow_sending_without_reply: bool = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
quote: bool = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
@@ -1641,8 +1694,8 @@ class Message(TelegramObject):
|
||||
def forward(
|
||||
self,
|
||||
chat_id: Union[int, str],
|
||||
disable_notification: bool = False,
|
||||
timeout: float = None,
|
||||
disable_notification: DVInput[bool] = DEFAULT_NONE,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> 'Message':
|
||||
"""Shortcut for::
|
||||
@@ -1672,13 +1725,13 @@ class Message(TelegramObject):
|
||||
self,
|
||||
chat_id: Union[int, str],
|
||||
caption: str = None,
|
||||
parse_mode: str = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_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,
|
||||
disable_notification: DVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: int = None,
|
||||
allow_sending_without_reply: DVInput[bool] = DEFAULT_NONE,
|
||||
reply_markup: ReplyMarkup = None,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> 'MessageId':
|
||||
"""Shortcut for::
|
||||
@@ -1713,15 +1766,15 @@ class Message(TelegramObject):
|
||||
def reply_copy(
|
||||
self,
|
||||
from_chat_id: Union[str, int],
|
||||
message_id: Union[str, int],
|
||||
message_id: int,
|
||||
caption: str = None,
|
||||
parse_mode: str = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_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,
|
||||
disable_notification: DVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: int = None,
|
||||
allow_sending_without_reply: DVInput[bool] = DEFAULT_NONE,
|
||||
reply_markup: ReplyMarkup = None,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
quote: bool = None,
|
||||
) -> 'MessageId':
|
||||
@@ -1766,10 +1819,10 @@ class Message(TelegramObject):
|
||||
def edit_text(
|
||||
self,
|
||||
text: str,
|
||||
parse_mode: str = None,
|
||||
disable_web_page_preview: bool = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
disable_web_page_preview: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_markup: InlineKeyboardMarkup = None,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
) -> Union['Message', bool]:
|
||||
@@ -1809,8 +1862,8 @@ class Message(TelegramObject):
|
||||
self,
|
||||
caption: str = None,
|
||||
reply_markup: InlineKeyboardMarkup = None,
|
||||
timeout: float = None,
|
||||
parse_mode: str = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
caption_entities: Union[List['MessageEntity'], Tuple['MessageEntity', ...]] = None,
|
||||
) -> Union['Message', bool]:
|
||||
@@ -1850,7 +1903,7 @@ class Message(TelegramObject):
|
||||
self,
|
||||
media: 'InputMedia' = None,
|
||||
reply_markup: InlineKeyboardMarkup = None,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> Union['Message', bool]:
|
||||
"""Shortcut for::
|
||||
@@ -1886,7 +1939,7 @@ class Message(TelegramObject):
|
||||
def edit_reply_markup(
|
||||
self,
|
||||
reply_markup: Optional['InlineKeyboardMarkup'] = None,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> Union['Message', bool]:
|
||||
"""Shortcut for::
|
||||
@@ -1923,7 +1976,7 @@ class Message(TelegramObject):
|
||||
longitude: float = None,
|
||||
location: Location = None,
|
||||
reply_markup: InlineKeyboardMarkup = None,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
horizontal_accuracy: float = None,
|
||||
heading: int = None,
|
||||
@@ -1966,7 +2019,7 @@ class Message(TelegramObject):
|
||||
def stop_live_location(
|
||||
self,
|
||||
reply_markup: InlineKeyboardMarkup = None,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> Union['Message', bool]:
|
||||
"""Shortcut for::
|
||||
@@ -2003,7 +2056,7 @@ class Message(TelegramObject):
|
||||
score: int,
|
||||
force: bool = None,
|
||||
disable_edit_message: bool = None,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> Union['Message', bool]:
|
||||
"""Shortcut for::
|
||||
@@ -2039,7 +2092,7 @@ class Message(TelegramObject):
|
||||
def get_game_high_scores(
|
||||
self,
|
||||
user_id: Union[int, str],
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> List['GameHighScore']:
|
||||
"""Shortcut for::
|
||||
@@ -2071,7 +2124,7 @@ class Message(TelegramObject):
|
||||
|
||||
def delete(
|
||||
self,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> bool:
|
||||
"""Shortcut for::
|
||||
@@ -2097,7 +2150,7 @@ class Message(TelegramObject):
|
||||
def stop_poll(
|
||||
self,
|
||||
reply_markup: InlineKeyboardMarkup = None,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> Poll:
|
||||
"""Shortcut for::
|
||||
@@ -2124,8 +2177,8 @@ class Message(TelegramObject):
|
||||
|
||||
def pin(
|
||||
self,
|
||||
disable_notification: bool = None,
|
||||
timeout: float = None,
|
||||
disable_notification: ODVInput[bool] = DEFAULT_NONE,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> bool:
|
||||
"""Shortcut for::
|
||||
@@ -2151,7 +2204,7 @@ class Message(TelegramObject):
|
||||
|
||||
def unpin(
|
||||
self,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> bool:
|
||||
"""Shortcut for::
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 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 change in the Telegram message auto
|
||||
deletion."""
|
||||
|
||||
from typing import Any
|
||||
|
||||
from telegram import TelegramObject
|
||||
|
||||
|
||||
class MessageAutoDeleteTimerChanged(TelegramObject):
|
||||
"""This object represents a service message about a change in auto-delete timer settings.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`message_auto_delete_time` is equal.
|
||||
|
||||
.. versionadded:: 13.4
|
||||
|
||||
Args:
|
||||
message_auto_delete_time (:obj:`int`): New auto-delete time for messages in the
|
||||
chat.
|
||||
**kwargs (:obj:`dict`): Arbitrary keyword arguments.
|
||||
|
||||
Attributes:
|
||||
message_auto_delete_time (:obj:`int`): New auto-delete time for messages in the
|
||||
chat.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
message_auto_delete_time: int,
|
||||
**_kwargs: Any,
|
||||
):
|
||||
self.message_auto_delete_time = int(message_auto_delete_time)
|
||||
|
||||
self._id_attrs = (self.message_auto_delete_time,)
|
||||
@@ -16,7 +16,7 @@
|
||||
#
|
||||
# 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=C0114, E0401, W0622
|
||||
# pylint: disable=C0114, W0622
|
||||
try:
|
||||
import ujson as json
|
||||
except ImportError:
|
||||
@@ -25,12 +25,21 @@ except ImportError:
|
||||
from base64 import b64decode
|
||||
from typing import TYPE_CHECKING, Any, List, Optional, Tuple, Union, no_type_check
|
||||
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from cryptography.hazmat.primitives.asymmetric.padding import MGF1, OAEP
|
||||
from cryptography.hazmat.primitives.ciphers import Cipher
|
||||
from cryptography.hazmat.primitives.ciphers.algorithms import AES
|
||||
from cryptography.hazmat.primitives.ciphers.modes import CBC
|
||||
from cryptography.hazmat.primitives.hashes import SHA1, SHA256, SHA512, Hash
|
||||
try:
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from cryptography.hazmat.primitives.asymmetric.padding import MGF1, OAEP
|
||||
from cryptography.hazmat.primitives.ciphers import Cipher
|
||||
from cryptography.hazmat.primitives.ciphers.algorithms import AES
|
||||
from cryptography.hazmat.primitives.ciphers.modes import CBC
|
||||
from cryptography.hazmat.primitives.hashes import SHA1, SHA256, SHA512, Hash
|
||||
|
||||
CRYPTO_INSTALLED = True
|
||||
except ImportError:
|
||||
default_backend = None
|
||||
MGF1, OAEP, Cipher, AES, CBC = (None, None, None, None, None) # type: ignore[misc]
|
||||
SHA1, SHA256, SHA512, Hash = (None, None, None, None) # type: ignore[misc]
|
||||
|
||||
CRYPTO_INSTALLED = False
|
||||
|
||||
from telegram import TelegramError, TelegramObject
|
||||
from telegram.utils.types import JSONDict
|
||||
@@ -74,6 +83,11 @@ def decrypt(secret, hash, data):
|
||||
:obj:`bytes`: The decrypted data as bytes.
|
||||
|
||||
"""
|
||||
if not CRYPTO_INSTALLED:
|
||||
raise RuntimeError(
|
||||
'To use Telegram Passports, PTB must be installed via `pip install '
|
||||
'python-telegram-bot[passport]`.'
|
||||
)
|
||||
# Make a SHA512 hash of secret + update
|
||||
digest = Hash(SHA512(), backend=default_backend())
|
||||
digest.update(secret + hash)
|
||||
@@ -153,6 +167,11 @@ class EncryptedCredentials(TelegramObject):
|
||||
private/public key but can also suggest malformed/tampered data.
|
||||
"""
|
||||
if self._decrypted_secret is None:
|
||||
if not CRYPTO_INSTALLED:
|
||||
raise RuntimeError(
|
||||
'To use Telegram Passports, PTB must be installed via `pip install '
|
||||
'python-telegram-bot[passport]`.'
|
||||
)
|
||||
# Try decrypting according to step 1 at
|
||||
# https://core.telegram.org/passport#decrypting-data
|
||||
# We make sure to base64 decode the secret first.
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
from typing import TYPE_CHECKING, Any, List, Optional
|
||||
|
||||
from telegram import TelegramObject
|
||||
from telegram.utils.types import JSONDict
|
||||
from telegram.utils.helpers import DEFAULT_NONE
|
||||
from telegram.utils.types import JSONDict, ODVInput
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import Bot, File, FileCredentials
|
||||
@@ -103,7 +104,9 @@ class PassportFile(TelegramObject):
|
||||
for i, passport_file in enumerate(data)
|
||||
]
|
||||
|
||||
def get_file(self, timeout: float = None, api_kwargs: JSONDict = None) -> 'File':
|
||||
def get_file(
|
||||
self, timeout: ODVInput[float] = DEFAULT_NONE, api_kwargs: JSONDict = None
|
||||
) -> 'File':
|
||||
"""
|
||||
Wrapper over :attr:`telegram.Bot.get_file`. Will automatically assign the correct
|
||||
credentials to the returned :class:`telegram.File` if originating from
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
from typing import TYPE_CHECKING, Any, Optional
|
||||
|
||||
from telegram import OrderInfo, TelegramObject, User
|
||||
from telegram.utils.types import JSONDict
|
||||
from telegram.utils.helpers import DEFAULT_NONE
|
||||
from telegram.utils.types import JSONDict, ODVInput
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import Bot
|
||||
@@ -34,7 +35,7 @@ class PreCheckoutQuery(TelegramObject):
|
||||
considered equal, if their :attr:`id` is equal.
|
||||
|
||||
Note:
|
||||
In Python `from` is a reserved word, use `from_user` instead.
|
||||
In Python ``from`` is a reserved word, use ``from_user`` instead.
|
||||
|
||||
Args:
|
||||
id (:obj:`str`): Unique query identifier.
|
||||
@@ -106,7 +107,7 @@ class PreCheckoutQuery(TelegramObject):
|
||||
self,
|
||||
ok: bool,
|
||||
error_message: str = None,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> bool:
|
||||
"""Shortcut for::
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
from typing import TYPE_CHECKING, Any, Optional, List
|
||||
|
||||
from telegram import ShippingAddress, TelegramObject, User, ShippingOption
|
||||
from telegram.utils.types import JSONDict
|
||||
from telegram.utils.helpers import DEFAULT_NONE
|
||||
from telegram.utils.types import JSONDict, ODVInput
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import Bot
|
||||
@@ -34,7 +35,7 @@ class ShippingQuery(TelegramObject):
|
||||
considered equal, if their :attr:`id` is equal.
|
||||
|
||||
Note:
|
||||
In Python `from` is a reserved word, use `from_user` instead.
|
||||
In Python ``from`` is a reserved word, use ``from_user`` instead.
|
||||
|
||||
Args:
|
||||
id (:obj:`str`): Unique query identifier.
|
||||
@@ -88,7 +89,7 @@ class ShippingQuery(TelegramObject):
|
||||
ok: bool,
|
||||
shipping_options: List[ShippingOption] = None,
|
||||
error_message: str = None,
|
||||
timeout: float = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> bool:
|
||||
"""Shortcut for::
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user