mirror of
https://github.com/python-telegram-bot/python-telegram-bot.git
synced 2026-06-20 16:15:28 +00:00
Compare commits
48 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9ef8826f33 | |||
| 61b70efb4c | |||
| 63977ea353 | |||
| ae57d3b7c3 | |||
| 8d76087bed | |||
| 0e90deafb5 | |||
| 39d45124df | |||
| 895403a0b5 | |||
| 8cb177cb2c | |||
| eaf802e07d | |||
| 1ef242a17e | |||
| 7adb4fa2db | |||
| 5c5ee598a2 | |||
| a4ae6f2097 | |||
| fc5a56c15b | |||
| 74112bfd06 | |||
| ab90cd7359 | |||
| 5b0f1697f1 | |||
| 9c7298c17a | |||
| 39abf838fa | |||
| 04b44f4595 | |||
| a0decdac28 | |||
| f77f4b0cf7 | |||
| 82c98b64a7 | |||
| f9ccf560f6 | |||
| 40ab8aadca | |||
| 644d76b592 | |||
| bd24da29cd | |||
| caffb9d66e | |||
| 1efd8e80ab | |||
| 8cc55c3381 | |||
| fbe9eeeaf5 | |||
| ebed8ec7d3 | |||
| 009785f028 | |||
| 7c858473ca | |||
| 58a109aae6 | |||
| 71eff4731c | |||
| c2c8c53d9c | |||
| 3b78934a77 | |||
| 5128748092 | |||
| 03f87750d4 | |||
| 4c4bf2185d | |||
| aaadc70fcc | |||
| ed3acd4b81 | |||
| a00ba52114 | |||
| 0ae991c141 | |||
| 7226aaea04 | |||
| 50a16edb41 |
@@ -17,3 +17,4 @@ enabled = true
|
||||
runtime_version = "3.x.x"
|
||||
max_line_length = 99
|
||||
skip_doc_coverage = ["module", "magic", "init", "nonpublic"]
|
||||
cyclomatic_complexity_threshold = "high"
|
||||
|
||||
@@ -167,6 +167,7 @@ Feel free to copy (parts of) the checklist to the PR description to remind you o
|
||||
**If the PR contains API changes (otherwise, you can ignore this passage)**
|
||||
|
||||
- Checked the Bot API specific sections of the `Stability Policy <https://docs.python-telegram-bot.org/stability_policy.html>`_
|
||||
- Created a PR to remove functionality deprecated in the previous Bot API release (`see here <https://docs.python-telegram-bot.org/en/stable/stability_policy.html#case-2>`_)
|
||||
|
||||
- New classes:
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<!--
|
||||
Hey! You're PRing? Cool!
|
||||
Please be sure to check out our contribution guide (https://github.com/python-telegram-bot/python-telegram-bot/blob/master/.github/CONTRIBUTING.rst).
|
||||
Especially, please have a look at the check list for PRs (https://github.com/python-telegram-bot/python-telegram-bot/blob/master/.github/CONTRIBUTING.rst#checklist-for-prs). Feel free to copy (parts of) the checklist to the PR description to remind you or the maintainers of open points or if you have questions on anything.
|
||||
Especially, please have a look at the check list for PRs (https://github.com/python-telegram-bot/python-telegram-bot/blob/master/.github/CONTRIBUTING.rst#check-list-for-prs). Feel free to copy (parts of) the checklist to the PR description to remind you or the maintainers of open points or if you have questions on anything.
|
||||
-->
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ name: Process Dependabot PRs
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
types: [opened, reopened]
|
||||
|
||||
jobs:
|
||||
process-dependabot-prs:
|
||||
@@ -18,7 +18,7 @@ jobs:
|
||||
id: dependabot-metadata
|
||||
uses: dependabot/fetch-metadata@v1.6.0
|
||||
|
||||
- uses: actions/checkout@v3.5.2
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.ref }}
|
||||
|
||||
@@ -35,4 +35,4 @@ jobs:
|
||||
with:
|
||||
message: 'Update version number in other files'
|
||||
committer_name: GitHub Actions
|
||||
committer_email: 41898282+github-actions[bot]@users.noreply.github.com
|
||||
committer_email: 41898282+github-actions[bot]@users.noreply.github.com
|
||||
|
||||
@@ -14,7 +14,7 @@ jobs:
|
||||
os: [ubuntu-latest]
|
||||
fail-fast: False
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
|
||||
@@ -19,7 +19,7 @@ jobs:
|
||||
os: [ubuntu-latest]
|
||||
fail-fast: False
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
|
||||
@@ -11,7 +11,7 @@ jobs:
|
||||
pull-requests: write # for srvaroa/labeler to add labels in PR
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: srvaroa/labeler@v1.6.0
|
||||
- uses: srvaroa/labeler@v1.6.1
|
||||
# Config file at .github/labeler.yml
|
||||
env:
|
||||
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
name: Bot API Tests
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
schedule:
|
||||
# Run monday and friday morning at 03:07 - odd time to spread load on GitHub Actions
|
||||
- cron: '7 3 * * 1,5'
|
||||
|
||||
jobs:
|
||||
check-conformity:
|
||||
name: check-conformity
|
||||
runs-on: ${{matrix.os}}
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [3.11]
|
||||
os: [ubuntu-latest]
|
||||
fail-fast: False
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -W ignore -m pip install --upgrade pip
|
||||
python -W ignore -m pip install -r requirements.txt
|
||||
python -W ignore -m pip install -r requirements-opts.txt
|
||||
python -W ignore -m pip install -r requirements-dev.txt
|
||||
- name: Compare to official api
|
||||
run: |
|
||||
pytest -v tests/test_official.py --junit-xml=.test_report_official.xml
|
||||
exit $?
|
||||
env:
|
||||
TEST_OFFICIAL: "true"
|
||||
shell: bash --noprofile --norc {0}
|
||||
|
||||
- name: Test Summary
|
||||
id: test_summary
|
||||
uses: test-summary/action@v2.1
|
||||
if: always() # always run, even if tests fail
|
||||
with:
|
||||
paths: .test_report_official.xml
|
||||
@@ -12,7 +12,7 @@ jobs:
|
||||
name: test-type-completeness
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- run: git fetch --depth=1 # https://github.com/actions/checkout/issues/329#issuecomment-674881489
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v4
|
||||
|
||||
@@ -16,11 +16,11 @@ jobs:
|
||||
runs-on: ${{matrix.os}}
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12.0-beta.3']
|
||||
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
|
||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||
fail-fast: False
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
@@ -92,38 +92,3 @@ jobs:
|
||||
env_vars: OS,PYTHON
|
||||
name: ${{ matrix.os }}-${{ matrix.python-version }}
|
||||
fail_ci_if_error: true
|
||||
|
||||
test_official:
|
||||
name: test-official
|
||||
runs-on: ${{matrix.os}}
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [3.11]
|
||||
os: [ubuntu-latest]
|
||||
fail-fast: False
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -W ignore -m pip install --upgrade pip
|
||||
python -W ignore -m pip install -r requirements.txt
|
||||
python -W ignore -m pip install -r requirements-opts.txt
|
||||
python -W ignore -m pip install -r requirements-dev.txt
|
||||
- name: Compare to official api
|
||||
run: |
|
||||
pytest -v tests/test_official.py --junit-xml=.test_report_official.xml
|
||||
exit $?
|
||||
env:
|
||||
TEST_OFFICIAL: "true"
|
||||
shell: bash --noprofile --norc {0}
|
||||
|
||||
- name: Test Summary
|
||||
id: test_summary
|
||||
uses: test-summary/action@v2.1
|
||||
if: always() # always run, even if tests fail
|
||||
with:
|
||||
paths: .test_report_official.xml
|
||||
+14
-14
@@ -6,18 +6,18 @@ ci:
|
||||
|
||||
repos:
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 23.3.0
|
||||
rev: 23.9.1
|
||||
hooks:
|
||||
- id: black
|
||||
args:
|
||||
- --diff
|
||||
- --check
|
||||
- repo: https://github.com/PyCQA/flake8
|
||||
rev: 6.0.0
|
||||
rev: 6.1.0
|
||||
hooks:
|
||||
- id: flake8
|
||||
- repo: https://github.com/PyCQA/pylint
|
||||
rev: v3.0.0a6
|
||||
rev: v3.0.0
|
||||
hooks:
|
||||
- id: pylint
|
||||
files: ^(telegram|examples)/.*\.py$
|
||||
@@ -29,13 +29,13 @@ repos:
|
||||
|
||||
additional_dependencies:
|
||||
- httpx~=0.24.1
|
||||
- tornado~=6.2
|
||||
- APScheduler~=3.10.1
|
||||
- tornado~=6.3.3
|
||||
- APScheduler~=3.10.4
|
||||
- cachetools~=5.3.1
|
||||
- aiolimiter~=1.1.0
|
||||
- . # this basically does `pip install -e .`
|
||||
- repo: https://github.com/pre-commit/mirrors-mypy
|
||||
rev: v1.4.1
|
||||
rev: v1.5.1
|
||||
hooks:
|
||||
- id: mypy
|
||||
name: mypy-ptb
|
||||
@@ -45,8 +45,8 @@ repos:
|
||||
- types-cryptography
|
||||
- types-cachetools
|
||||
- httpx~=0.24.1
|
||||
- tornado~=6.2
|
||||
- APScheduler~=3.10.1
|
||||
- tornado~=6.3.3
|
||||
- APScheduler~=3.10.4
|
||||
- cachetools~=5.3.1
|
||||
- aiolimiter~=1.1.0
|
||||
- . # this basically does `pip install -e .`
|
||||
@@ -57,12 +57,12 @@ repos:
|
||||
- --no-strict-optional
|
||||
- --follow-imports=silent
|
||||
additional_dependencies:
|
||||
- tornado~=6.2
|
||||
- APScheduler~=3.10.1
|
||||
- tornado~=6.3.3
|
||||
- APScheduler~=3.10.4
|
||||
- cachetools~=5.3.1
|
||||
- . # this basically does `pip install -e .`
|
||||
- repo: https://github.com/asottile/pyupgrade
|
||||
rev: v3.8.0
|
||||
rev: v3.13.0
|
||||
hooks:
|
||||
- id: pyupgrade
|
||||
files: ^(telegram|examples|tests|docs)/.*\.py$
|
||||
@@ -77,14 +77,14 @@ repos:
|
||||
- --diff
|
||||
- --check
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
rev: 'v0.0.277'
|
||||
rev: 'v0.0.292'
|
||||
hooks:
|
||||
- id: ruff
|
||||
name: ruff
|
||||
files: ^(telegram|examples|tests)/.*\.py$
|
||||
additional_dependencies:
|
||||
- httpx~=0.24.1
|
||||
- tornado~=6.2
|
||||
- APScheduler~=3.10.1
|
||||
- tornado~=6.3.3
|
||||
- APScheduler~=3.10.4
|
||||
- cachetools~=5.3.1
|
||||
- aiolimiter~=1.1.0
|
||||
|
||||
@@ -21,6 +21,7 @@ Contributors
|
||||
|
||||
The following wonderful people contributed directly or indirectly to this project:
|
||||
|
||||
- `Abdelrahman <https://github.com/aelkheir>`_
|
||||
- `Abshar <https://github.com/abxhr>`_
|
||||
- `Alateas <https://github.com/alateas>`_
|
||||
- `Ales Dokshanin <https://github.com/alesdokshanin>`_
|
||||
@@ -120,6 +121,7 @@ The following wonderful people contributed directly or indirectly to this projec
|
||||
- `Wagner Macedo <https://github.com/wagnerluis1982>`_
|
||||
- `wjt <https://github.com/wjt>`_
|
||||
- `Yaw Danso <https://github.com/dglitxh>`_
|
||||
- `Yao Kuan <https://github.com/thatguylah>`_
|
||||
- `zeroone2numeral2 <https://github.com/zeroone2numeral2>`_
|
||||
- `zeshuaro <https://github.com/zeshuaro>`_
|
||||
- `zpavloudis <https://github.com/zpavloudis>`_
|
||||
|
||||
+101
@@ -4,6 +4,107 @@
|
||||
Changelog
|
||||
=========
|
||||
|
||||
Version 20.6
|
||||
============
|
||||
|
||||
*Released 2023-10-03*
|
||||
|
||||
This is the technical changelog for version 20.6. More elaborate release notes can be found in the news channel `@pythontelegrambotchannel <https://t.me/pythontelegrambotchannel>`__.
|
||||
|
||||
Major Changes
|
||||
-------------
|
||||
|
||||
- Drop Backward Compatibility Layer Introduced in :pr:`3853` (API 6.8) (:pr:`3873`)
|
||||
- Full Support for Bot API 6.9 (:pr:`3898`)
|
||||
|
||||
New Features
|
||||
------------
|
||||
|
||||
- Add Rich Equality Comparison to ``WriteAccessAllowed`` (:pr:`3911` closes :issue:`3909`)
|
||||
- Add ``__repr__`` Methods Added in :pr:`3826` closes :issue:`3770` to Sphinx Documentation (:pr:`3901` closes :issue:`3889`)
|
||||
- Add String Representation for Selected Classes (:pr:`3826` closes :issue:`3770`)
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- Add Support Python 3.12 (:pr:`3915`)
|
||||
- Documentation Improvements (:pr:`3910`)
|
||||
|
||||
Internal Changes
|
||||
----------------
|
||||
|
||||
- Verify Type Hints for Bot Method & Telegram Class Parameters (:pr:`3868`)
|
||||
- Move Bot API Tests to Separate Workflow File (:pr:`3912`)
|
||||
- Fix Failing ``file_size`` Tests (:pr:`3906`)
|
||||
- Set Threshold for DeepSource’s PY-R1000 to High (:pr:`3888`)
|
||||
- One-Time Code Formatting Improvement via ``--preview`` Flag of ``black`` (:pr:`3882`)
|
||||
- Move Dunder Methods to the Top of Class Bodies (:pr:`3883`)
|
||||
- Remove Superfluous ``Defaults.__ne__`` (:pr:`3884`)
|
||||
|
||||
Dependency Updates
|
||||
------------------
|
||||
|
||||
- ``pre-commit`` autoupdate (:pr:`3876`)
|
||||
- Update ``pre-commit`` Dependencies (:pr:`3916`)
|
||||
- Bump ``actions/checkout`` from 3 to 4 (:pr:`3914`)
|
||||
- Update ``httpx`` requirement from ~=0.24.1 to ~=0.25.0 (:pr:`3891`)
|
||||
- Bump ``furo`` from 2023.8.19 to 2023.9.10 (:pr:`3890`)
|
||||
- Bump ``sphinx`` from 7.2.5 to 7.2.6 (:pr:`3892`)
|
||||
- Update ``tornado`` requirement from ~=6.2 to ~=6.3.3 (:pr:`3675`)
|
||||
- Bump ``pytest`` from 7.4.0 to 7.4.2 (:pr:`3881`)
|
||||
|
||||
|
||||
Version 20.5
|
||||
============
|
||||
*Released 2023-09-03*
|
||||
|
||||
This is the technical changelog for version 20.5. More elaborate release notes can be found in the news channel `@pythontelegrambotchannel <https://t.me/pythontelegrambotchannel>`__.
|
||||
|
||||
Major Changes
|
||||
-------------
|
||||
|
||||
- API 6.8 (:pr:`3853`)
|
||||
- Remove Functionality Deprecated Since Bot API 6.5, 6.6 or 6.7 (:pr:`3858`)
|
||||
|
||||
New Features
|
||||
------------
|
||||
|
||||
- Extend Allowed Values for HTTP Version (:pr:`3823` closes :issue:`3821`)
|
||||
- Add ``has_args`` Parameter to ``CommandHandler`` (:pr:`3854` by `@thatguylah <https://github.com/thatguylah>`__ closes :issue:`3798`)
|
||||
- Add ``Application.stop_running()`` and Improve Marking Updates as Read on ``Updater.stop()`` (:pr:`3804`)
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- Type Hinting Fixes for ``WebhookInfo`` (:pr:`3871`)
|
||||
- Test and Document ``Exception.__cause__`` on ``NetworkError`` (:pr:`3792` closes :issue:`3778`)
|
||||
- Add Support for Python 3.12 RC (:pr:`3847`)
|
||||
|
||||
Documentation Improvements
|
||||
--------------------------
|
||||
|
||||
- Remove Version Check from Examples (:pr:`3846`)
|
||||
- Documentation Improvements (:pr:`3803`, :pr:`3797`, :pr:`3816` by `@trim21 <https://github.com/trim21>`__, :pr:`3829` by `@aelkheir <https://github.com/aelkheir>`__)
|
||||
- Provide Versions of ``customwebhookbot.py`` with Different Frameworks (:pr:`3820` closes :issue:`3717`)
|
||||
|
||||
Dependency Updates
|
||||
------------------
|
||||
|
||||
- ``pre-commit`` autoupdate (:pr:`3824`)
|
||||
- Bump ``srvaroa/labeler`` from 1.6.0 to 1.6.1 (:pr:`3870`)
|
||||
- Bump ``sphinx`` from 7.0.1 to 7.1.1 (:pr:`3818`)
|
||||
- Bump ``sphinx`` from 7.2.3 to 7.2.5 (:pr:`3869`)
|
||||
- Bump ``furo`` from 2023.5.20 to 2023.7.26 (:pr:`3817`)
|
||||
- Update ``apscheduler`` requirement from ~=3.10.3 to ~=3.10.4 (:pr:`3862`)
|
||||
- Bump ``sphinx`` from 7.2.2 to 7.2.3 (:pr:`3861`)
|
||||
- Bump ``pytest-asyncio`` from 0.21.0 to 0.21.1 (:pr:`3801`)
|
||||
- Bump ``sphinx-paramlinks`` from 0.5.4 to 0.6.0 (:pr:`3840`)
|
||||
- Update ``apscheduler`` requirement from ~=3.10.1 to ~=3.10.3 (:pr:`3851`)
|
||||
- Bump ``furo`` from 2023.7.26 to 2023.8.19 (:pr:`3850`)
|
||||
- Bump ``sphinx`` from 7.1.2 to 7.2.2 (:pr:`3852`)
|
||||
- Bump ``sphinx`` from 7.1.1 to 7.1.2 (:pr:`3827`)
|
||||
|
||||
|
||||
Version 20.4
|
||||
============
|
||||
|
||||
|
||||
+5
-5
@@ -14,7 +14,7 @@
|
||||
:target: https://pypi.org/project/python-telegram-bot/
|
||||
:alt: Supported Python versions
|
||||
|
||||
.. image:: https://img.shields.io/badge/Bot%20API-6.7-blue?logo=telegram
|
||||
.. image:: https://img.shields.io/badge/Bot%20API-6.9-blue?logo=telegram
|
||||
:target: https://core.telegram.org/bots/api-changelog
|
||||
:alt: Supported Bot API versions
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
:target: https://www.gnu.org/licenses/lgpl-3.0.html
|
||||
:alt: LGPLv3 License
|
||||
|
||||
.. image:: https://github.com/python-telegram-bot/python-telegram-bot/workflows/GitHub%20Actions/badge.svg
|
||||
.. image:: https://github.com/python-telegram-bot/python-telegram-bot/workflows/Unit%20Tests/badge.svg
|
||||
:target: https://github.com/python-telegram-bot/python-telegram-bot/
|
||||
:alt: Github Actions workflow
|
||||
|
||||
@@ -93,7 +93,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 **6.7** are supported.
|
||||
All types and methods of the Telegram Bot API **6.9** are supported.
|
||||
|
||||
Installing
|
||||
==========
|
||||
@@ -152,9 +152,9 @@ PTB can be installed with optional dependencies:
|
||||
* ``pip install "python-telegram-bot[socks]"`` installs `httpx[socks] <https://www.python-httpx.org/#dependencies>`_. Use this, if you want to work behind a Socks5 server.
|
||||
* ``pip install "python-telegram-bot[http2]"`` installs `httpx[http2] <https://www.python-httpx.org/#dependencies>`_. Use this, if you want to use HTTP/2.
|
||||
* ``pip install "python-telegram-bot[rate-limiter]"`` installs `aiolimiter~=1.1.0 <https://aiolimiter.readthedocs.io/en/stable/>`_. Use this, if you want to use ``telegram.ext.AIORateLimiter``.
|
||||
* ``pip install "python-telegram-bot[webhooks]"`` installs the `tornado~=6.2 <https://www.tornadoweb.org/en/stable/>`_ library. Use this, if you want to use ``telegram.ext.Updater.start_webhook``/``telegram.ext.Application.run_webhook``.
|
||||
* ``pip install "python-telegram-bot[webhooks]"`` installs the `tornado~=6.3.3 <https://www.tornadoweb.org/en/stable/>`_ library. Use this, if you want to use ``telegram.ext.Updater.start_webhook``/``telegram.ext.Application.run_webhook``.
|
||||
* ``pip install "python-telegram-bot[callback-data]"`` installs the `cachetools~=5.3.1 <https://cachetools.readthedocs.io/en/latest/>`_ library. Use this, if you want to use `arbitrary callback_data <https://github.com/python-telegram-bot/python-telegram-bot/wiki/Arbitrary-callback_data>`_.
|
||||
* ``pip install "python-telegram-bot[job-queue]"`` installs the `APScheduler~=3.10.1 <https://apscheduler.readthedocs.io/en/3.x/>`_ library and enforces `pytz>=2018.6 <https://pypi.org/project/pytz/>`_, where ``pytz`` is a dependency of ``APScheduler``. Use this, if you want to use the ``telegram.ext.JobQueue``.
|
||||
* ``pip install "python-telegram-bot[job-queue]"`` installs the `APScheduler~=3.10.4 <https://apscheduler.readthedocs.io/en/3.x/>`_ library and enforces `pytz>=2018.6 <https://pypi.org/project/pytz/>`_, where ``pytz`` is a dependency of ``APScheduler``. Use this, if you want to use the ``telegram.ext.JobQueue``.
|
||||
|
||||
To install multiple optional dependencies, separate them by commas, e.g. ``pip install "python-telegram-bot[socks,webhooks]"``.
|
||||
|
||||
|
||||
+3
-3
@@ -14,7 +14,7 @@
|
||||
:target: https://pypi.org/project/python-telegram-bot-raw/
|
||||
:alt: Supported Python versions
|
||||
|
||||
.. image:: https://img.shields.io/badge/Bot%20API-6.7-blue?logo=telegram
|
||||
.. image:: https://img.shields.io/badge/Bot%20API-6.9-blue?logo=telegram
|
||||
:target: https://core.telegram.org/bots/api-changelog
|
||||
:alt: Supported Bot API versions
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
:target: https://www.gnu.org/licenses/lgpl-3.0.html
|
||||
:alt: LGPLv3 License
|
||||
|
||||
.. image:: https://github.com/python-telegram-bot/python-telegram-bot/workflows/GitHub%20Actions/badge.svg
|
||||
.. image:: https://github.com/python-telegram-bot/python-telegram-bot/workflows/Unit%20Tests/badge.svg
|
||||
:target: https://github.com/python-telegram-bot/python-telegram-bot/
|
||||
:alt: Github Actions workflow
|
||||
|
||||
@@ -89,7 +89,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 **6.7** are supported.
|
||||
All types and methods of the Telegram Bot API **6.9** are supported.
|
||||
|
||||
Installing
|
||||
==========
|
||||
|
||||
@@ -194,7 +194,7 @@ class AdmonitionInserter:
|
||||
)
|
||||
except NotImplementedError as e:
|
||||
raise NotImplementedError(
|
||||
f"Error generating Sphinx 'Available in' admonition "
|
||||
"Error generating Sphinx 'Available in' admonition "
|
||||
f"(admonition_inserter.py). Class {name_of_class_in_attr} present in "
|
||||
f"attribute {target_attr} of class {name_of_inspected_class_in_docstr}"
|
||||
f" could not be resolved. {str(e)}"
|
||||
@@ -237,7 +237,7 @@ class AdmonitionInserter:
|
||||
)
|
||||
except NotImplementedError as e:
|
||||
raise NotImplementedError(
|
||||
f"Error generating Sphinx 'Available in' admonition "
|
||||
"Error generating Sphinx 'Available in' admonition "
|
||||
f"(admonition_inserter.py). Class {name_of_class_in_prop} present in "
|
||||
f"property {prop_name} of class {name_of_inspected_class_in_docstr}"
|
||||
f" could not be resolved. {str(e)}"
|
||||
@@ -269,7 +269,7 @@ class AdmonitionInserter:
|
||||
)
|
||||
except NotImplementedError as e:
|
||||
raise NotImplementedError(
|
||||
f"Error generating Sphinx 'Returned in' admonition "
|
||||
"Error generating Sphinx 'Returned in' admonition "
|
||||
f"(admonition_inserter.py). {cls}, method {method_name}. "
|
||||
f"Couldn't resolve type hint in return annotation {ret_annot}. {str(e)}"
|
||||
)
|
||||
@@ -342,7 +342,7 @@ class AdmonitionInserter:
|
||||
)
|
||||
except NotImplementedError as e:
|
||||
raise NotImplementedError(
|
||||
f"Error generating Sphinx 'Use in' admonition "
|
||||
"Error generating Sphinx 'Use in' admonition "
|
||||
f"(admonition_inserter.py). {cls}, method {method_name}, parameter "
|
||||
f"{param}: Couldn't resolve type hint {param.annotation}. {str(e)}"
|
||||
)
|
||||
|
||||
@@ -18,31 +18,47 @@
|
||||
import inspect
|
||||
|
||||
keyword_args = [
|
||||
":keyword _sphinx_paramlinks_telegram.Bot.{method}.read_timeout: Value to pass to "
|
||||
":paramref:`telegram.request.BaseRequest.post.read_timeout`. Defaults to {read_timeout}.",
|
||||
(
|
||||
":keyword _sphinx_paramlinks_telegram.Bot.{method}.read_timeout: Value to pass to "
|
||||
":paramref:`telegram.request.BaseRequest.post.read_timeout`. Defaults to {read_timeout}."
|
||||
),
|
||||
":kwtype _sphinx_paramlinks_telegram.Bot.{method}.read_timeout: {read_timeout_type}, optional",
|
||||
":keyword _sphinx_paramlinks_telegram.Bot.{method}.write_timeout: Value to pass to "
|
||||
":paramref:`telegram.request.BaseRequest.post.write_timeout`. Defaults to {write_timeout}.",
|
||||
":kwtype _sphinx_paramlinks_telegram.Bot.{method}.write_timeout: :obj:`float` | :obj:`None`, "
|
||||
"optional",
|
||||
":keyword _sphinx_paramlinks_telegram.Bot.{method}.connect_timeout: Value to pass to "
|
||||
":paramref:`telegram.request.BaseRequest.post.connect_timeout`. Defaults to "
|
||||
":attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.",
|
||||
":kwtype _sphinx_paramlinks_telegram.Bot.{method}.connect_timeout: :obj:`float` | "
|
||||
":obj:`None`, optional",
|
||||
":keyword _sphinx_paramlinks_telegram.Bot.{method}.pool_timeout: Value to pass to "
|
||||
":paramref:`telegram.request.BaseRequest.post.pool_timeout`. Defaults to "
|
||||
":attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.",
|
||||
":kwtype _sphinx_paramlinks_telegram.Bot.{method}.pool_timeout: :obj:`float` | :obj:`None`, "
|
||||
"optional",
|
||||
":keyword _sphinx_paramlinks_telegram.Bot.{method}.api_kwargs: Arbitrary keyword arguments "
|
||||
"to be passed to the Telegram API.",
|
||||
(
|
||||
":keyword _sphinx_paramlinks_telegram.Bot.{method}.write_timeout: Value to pass to "
|
||||
":paramref:`telegram.request.BaseRequest.post.write_timeout`. Defaults to {write_timeout}."
|
||||
),
|
||||
(
|
||||
":kwtype _sphinx_paramlinks_telegram.Bot.{method}.write_timeout: :obj:`float` |"
|
||||
" :obj:`None`, optional"
|
||||
),
|
||||
(
|
||||
":keyword _sphinx_paramlinks_telegram.Bot.{method}.connect_timeout: Value to pass to "
|
||||
":paramref:`telegram.request.BaseRequest.post.connect_timeout`. Defaults to "
|
||||
":attr:`~telegram.request.BaseRequest.DEFAULT_NONE`."
|
||||
),
|
||||
(
|
||||
":kwtype _sphinx_paramlinks_telegram.Bot.{method}.connect_timeout: :obj:`float` | "
|
||||
":obj:`None`, optional"
|
||||
),
|
||||
(
|
||||
":keyword _sphinx_paramlinks_telegram.Bot.{method}.pool_timeout: Value to pass to "
|
||||
":paramref:`telegram.request.BaseRequest.post.pool_timeout`. Defaults to "
|
||||
":attr:`~telegram.request.BaseRequest.DEFAULT_NONE`."
|
||||
),
|
||||
(
|
||||
":kwtype _sphinx_paramlinks_telegram.Bot.{method}.pool_timeout: :obj:`float` |"
|
||||
" :obj:`None`, optional"
|
||||
),
|
||||
(
|
||||
":keyword _sphinx_paramlinks_telegram.Bot.{method}.api_kwargs: Arbitrary keyword arguments"
|
||||
" to be passed to the Telegram API."
|
||||
),
|
||||
":kwtype _sphinx_paramlinks_telegram.Bot.{method}.api_kwargs: :obj:`dict`, optional",
|
||||
"",
|
||||
]
|
||||
write_timeout_sub = [":attr:`~telegram.request.BaseRequest.DEFAULT_NONE`", "``20``"]
|
||||
read_timeout_sub = [
|
||||
":attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.",
|
||||
":attr:`~telegram.request.BaseRequest.DEFAULT_NONE`",
|
||||
"``2``. :paramref:`timeout` will be added to this value",
|
||||
]
|
||||
read_timeout_type = [":obj:`float` | :obj:`None`", ":obj:`float`"]
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
sphinx==7.0.1
|
||||
sphinx==7.2.6
|
||||
sphinx-pypi-upload
|
||||
furo==2023.5.20
|
||||
git+https://github.com/harshil21/furo-sphinx-search@01efc7be422d7dc02390aab9be68d6f5ce1a5618#egg=furo-sphinx-search
|
||||
sphinx-paramlinks==0.5.4
|
||||
furo==2023.9.10
|
||||
git+https://github.com/harshil21/furo-sphinx-search@v0.2.0.1
|
||||
sphinx-paramlinks==0.6.0
|
||||
sphinxcontrib-mermaid==0.9.2
|
||||
sphinx-copybutton==0.5.2
|
||||
sphinx-inline-tabs==2023.4.21
|
||||
|
||||
+63
-52
@@ -21,9 +21,9 @@ author = "Leandro Toledo"
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = "20.4" # telegram.__version__[:3]
|
||||
version = "20.6" # telegram.__version__[:3]
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = "20.3" # telegram.__version__
|
||||
release = "20.6" # telegram.__version__
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
needs_sphinx = "6.1.3"
|
||||
@@ -39,6 +39,7 @@ extensions = [
|
||||
"sphinx.ext.extlinks",
|
||||
"sphinx_paramlinks",
|
||||
"sphinx_copybutton",
|
||||
"sphinx_inline_tabs",
|
||||
"sphinxcontrib.mermaid",
|
||||
"sphinx_search.extension",
|
||||
]
|
||||
@@ -95,7 +96,9 @@ linkcheck_ignore = [
|
||||
]
|
||||
linkcheck_allowed_redirects = {
|
||||
# Redirects to the default version are okay
|
||||
r"https://docs\.python-telegram-bot\.org/.*": r"https://docs\.python-telegram-bot\.org/en/[\w\d\.]+/.*",
|
||||
r"https://docs\.python-telegram-bot\.org/.*": (
|
||||
r"https://docs\.python-telegram-bot\.org/en/[\w\d\.]+/.*"
|
||||
),
|
||||
# pre-commit.ci always redirects to the latest run
|
||||
re.escape(
|
||||
"https://results.pre-commit.ci/latest/github/python-telegram-bot/python-telegram-bot/master"
|
||||
@@ -130,71 +133,79 @@ html_theme_options = {
|
||||
"admonition-title-font-size": "0.95rem",
|
||||
"admonition-font-size": "0.92rem",
|
||||
},
|
||||
"announcement": "PTB has undergone significant changes in v20. Please read the documentation "
|
||||
"carefully and also check out the transition guide in the "
|
||||
'<a href="https://github.com/python-telegram-bot/python-telegram-bot/wiki/'
|
||||
'Transition-guide-to-Version-20.0">wiki</a>.',
|
||||
"announcement": (
|
||||
"PTB has undergone significant changes in v20. Please read the documentation "
|
||||
"carefully and also check out the transition guide in the "
|
||||
'<a href="https://github.com/python-telegram-bot/python-telegram-bot/wiki/'
|
||||
'Transition-guide-to-Version-20.0">wiki</a>.'
|
||||
),
|
||||
"footer_icons": [
|
||||
{
|
||||
# Telegram channel logo
|
||||
"name": "Telegram Channel",
|
||||
"url": "https://t.me/pythontelegrambotchannel/",
|
||||
# Following svg is from https://react-icons.github.io/react-icons/search?q=telegram
|
||||
"html": '<svg stroke="currentColor" fill="currentColor" stroke-width="0" '
|
||||
'viewBox="0 0 16 16" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg">'
|
||||
'<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM8.287 5.906c-.778.324-2.334.994'
|
||||
"-4.666 2.01-.378.15-.577.298-.595.442-.03.243.275.339.69.47l.175.055c.408.133."
|
||||
"958.288 1.243.294.26.006.549-.1.868-.32 2.179-1.471 3.304-2.214 3.374-2.23.0"
|
||||
"5-.012.12-.026.166.016.047.041.042.12.037.141-.03.129-1.227 1.241-1.846 1.81"
|
||||
"7-.193.18-.33.307-.358.336a8.154 8.154 0 0 1-.188.186c-.38.366-.664.64.015 1.08"
|
||||
"8.327.216.589.393.85.571.284.194.568.387.936.629.093.06.183.125.27.187.331.23"
|
||||
"6.63.448.997.414.214-.02.435-.22.547-.82.265-1.417.786-4.486.906-5.751a1.426 "
|
||||
"1.426 0 0 0-.013-.315.337.337 0 0 0-.114-.217.526.526 0 0 0-.31-.093c-.3.005-.7"
|
||||
'63.166-2.984 1.09z"></path></svg>',
|
||||
"html": (
|
||||
'<svg stroke="currentColor" fill="currentColor" stroke-width="0" '
|
||||
'viewBox="0 0 16 16" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg">'
|
||||
'<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM8.287 5.906c-.778.324-2.334.994'
|
||||
"-4.666 2.01-.378.15-.577.298-.595.442-.03.243.275.339.69.47l.175.055c.408.133."
|
||||
"958.288 1.243.294.26.006.549-.1.868-.32 2.179-1.471 3.304-2.214 3.374-2.23.0"
|
||||
"5-.012.12-.026.166.016.047.041.042.12.037.141-.03.129-1.227 1.241-1.846 1.81"
|
||||
"7-.193.18-.33.307-.358.336a8.154 8.154 0 0 1-.188.186c-.38.366-.664.64.015 1.08"
|
||||
"8.327.216.589.393.85.571.284.194.568.387.936.629.093.06.183.125.27.187.331.23"
|
||||
"6.63.448.997.414.214-.02.435-.22.547-.82.265-1.417.786-4.486.906-5.751a1.426 "
|
||||
"1.426 0 0 0-.013-.315.337.337 0 0 0-.114-.217.526.526 0 0 0-.31-.093c-.3.005-.7"
|
||||
'63.166-2.984 1.09z"></path></svg>'
|
||||
),
|
||||
"class": "",
|
||||
},
|
||||
{ # Github logo
|
||||
"name": "GitHub",
|
||||
"url": "https://github.com/python-telegram-bot/python-telegram-bot/",
|
||||
"html": '<svg stroke="currentColor" fill="currentColor" stroke-width="0" '
|
||||
'viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 '
|
||||
"2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.4"
|
||||
"9-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23"
|
||||
".82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 "
|
||||
"0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.2"
|
||||
"7 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.5"
|
||||
"1.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 "
|
||||
'1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z">'
|
||||
"</path></svg>",
|
||||
"html": (
|
||||
'<svg stroke="currentColor" fill="currentColor" stroke-width="0" '
|
||||
'viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 '
|
||||
"2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.4"
|
||||
"9-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23"
|
||||
".82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 "
|
||||
"0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.2"
|
||||
"7 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.5"
|
||||
"1.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 "
|
||||
'1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z">'
|
||||
"</path></svg>"
|
||||
),
|
||||
"class": "",
|
||||
},
|
||||
{ # PTB website logo - globe
|
||||
"name": "python-telegram-bot website",
|
||||
"url": "https://python-telegram-bot.org/",
|
||||
"html": '<svg stroke="currentColor" fill="currentColor" stroke-width="0" '
|
||||
'viewBox="0 0 16 16" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg">'
|
||||
'<path d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8zm7.5-6.923c-.67.204-1.335.82-1.887 '
|
||||
"1.855-.143.268-.276.56-.395.872.705.157 1.472.257 2.282.287V1.077zM4.249 3.53"
|
||||
"9c.142-.384.304-.744.481-1.078a6.7 6.7 0 0 1 .597-.933A7.01 7.01 0 0 0 3.051 "
|
||||
"3.05c.362.184.763.349 1.198.49zM3.509 7.5c.036-1.07.188-2.087.436-3.008a9.124 "
|
||||
"9.124 0 0 1-1.565-.667A6.964 6.964 0 0 0 1.018 7.5h2.49zm1.4-2.741a12.344 "
|
||||
"12.344 0 0 0-.4 2.741H7.5V5.091c-.91-.03-1.783-.145-2.591-.332zM8.5 5.09V7.5h"
|
||||
"2.99a12.342 12.342 0 0 0-.399-2.741c-.808.187-1.681.301-2.591.332zM4.51 8.5c.03"
|
||||
"5.987.176 1.914.399 2.741A13.612 13.612 0 0 1 7.5 10.91V8.5H4.51zm3.99 0v2.409"
|
||||
"c.91.03 1.783.145 2.591.332.223-.827.364-1.754.4-2.741H8.5zm-3.282 3.696c.12.31"
|
||||
"2.252.604.395.872.552 1.035 1.218 1.65 1.887 1.855V11.91c-.81.03-1.577.13-2.28"
|
||||
"2.287zm.11 2.276a6.696 6.696 0 0 1-.598-.933 8.853 8.853 0 0 1-.481-1.079 8.38 "
|
||||
"8.38 0 0 0-1.198.49 7.01 7.01 0 0 0 2.276 1.522zm-1.383-2.964A13.36 13.36 0 0 1"
|
||||
" 3.508 8.5h-2.49a6.963 6.963 0 0 0 1.362 3.675c.47-.258.995-.482 1.565-.667zm"
|
||||
"6.728 2.964a7.009 7.009 0 0 0 2.275-1.521 8.376 8.376 0 0 0-1.197-.49 8.853 "
|
||||
"8.853 0 0 1-.481 1.078 6.688 6.688 0 0 1-.597.933zM8.5 11.909v3.014c.67-.204 "
|
||||
"1.335-.82 1.887-1.855.143-.268.276-.56.395-.872A12.63 12.63 0 0 0 8.5 11.91zm"
|
||||
"3.555-.401c.57.185 1.095.409 1.565.667A6.963 6.963 0 0 0 14.982 8.5h-2.49a1"
|
||||
"3.36 13.36 0 0 1-.437 3.008zM14.982 7.5a6.963 6.963 0 0 0-1.362-3.675c-.47.25"
|
||||
"8-.995.482-1.565.667.248.92.4 1.938.437 3.008h2.49zM11.27 2.461c.177.334.339.6"
|
||||
"94.482 1.078a8.368 8.368 0 0 0 1.196-.49 7.01 7.01 0 0 0-2.275-1.52c.218.283.4"
|
||||
"18.597.597.932zm-.488 1.343a7.765 7.765 0 0 0-.395-.872C9.835 1.897 9.17 1.282 "
|
||||
'8.5 1.077V4.09c.81-.03 1.577-.13 2.282-.287z"></path></svg>',
|
||||
"html": (
|
||||
'<svg stroke="currentColor" fill="currentColor" stroke-width="0" '
|
||||
'viewBox="0 0 16 16" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg">'
|
||||
'<path d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8zm7.5-6.923c-.67.204-1.335.82-1.887 '
|
||||
"1.855-.143.268-.276.56-.395.872.705.157 1.472.257 2.282.287V1.077zM4.249 3.53"
|
||||
"9c.142-.384.304-.744.481-1.078a6.7 6.7 0 0 1 .597-.933A7.01 7.01 0 0 0 3.051 "
|
||||
"3.05c.362.184.763.349 1.198.49zM3.509 7.5c.036-1.07.188-2.087.436-3.008a9.124 "
|
||||
"9.124 0 0 1-1.565-.667A6.964 6.964 0 0 0 1.018 7.5h2.49zm1.4-2.741a12.344 "
|
||||
"12.344 0 0 0-.4 2.741H7.5V5.091c-.91-.03-1.783-.145-2.591-.332zM8.5 5.09V7.5h"
|
||||
"2.99a12.342 12.342 0 0 0-.399-2.741c-.808.187-1.681.301-2.591.332zM4.51 8.5c.03"
|
||||
"5.987.176 1.914.399 2.741A13.612 13.612 0 0 1 7.5 10.91V8.5H4.51zm3.99 0v2.409"
|
||||
"c.91.03 1.783.145 2.591.332.223-.827.364-1.754.4-2.741H8.5zm-3.282 3.696c.12.31"
|
||||
"2.252.604.395.872.552 1.035 1.218 1.65 1.887 1.855V11.91c-.81.03-1.577.13-2.28"
|
||||
"2.287zm.11 2.276a6.696 6.696 0 0 1-.598-.933 8.853 8.853 0 0 1-.481-1.079 8.38 "
|
||||
"8.38 0 0 0-1.198.49 7.01 7.01 0 0 0 2.276 1.522zm-1.383-2.964A13.36 13.36 0 0 1"
|
||||
" 3.508 8.5h-2.49a6.963 6.963 0 0 0 1.362 3.675c.47-.258.995-.482 1.565-.667zm"
|
||||
"6.728 2.964a7.009 7.009 0 0 0 2.275-1.521 8.376 8.376 0 0 0-1.197-.49 8.853 "
|
||||
"8.853 0 0 1-.481 1.078 6.688 6.688 0 0 1-.597.933zM8.5 11.909v3.014c.67-.204 "
|
||||
"1.335-.82 1.887-1.855.143-.268.276-.56.395-.872A12.63 12.63 0 0 0 8.5 11.91zm"
|
||||
"3.555-.401c.57.185 1.095.409 1.565.667A6.963 6.963 0 0 0 14.982 8.5h-2.49a1"
|
||||
"3.36 13.36 0 0 1-.437 3.008zM14.982 7.5a6.963 6.963 0 0 0-1.362-3.675c-.47.25"
|
||||
"8-.995.482-1.565.667.248.92.4 1.938.437 3.008h2.49zM11.27 2.461c.177.334.339.6"
|
||||
"94.482 1.078a8.368 8.368 0 0 0 1.196-.49 7.01 7.01 0 0 0-2.275-1.52c.218.283.4"
|
||||
"18.597.597.932zm-.488 1.343a7.765 7.765 0 0 0-.395-.872C9.835 1.897 9.17 1.282 "
|
||||
'8.5 1.077V4.09c.81-.03 1.577-.13 2.282-.287z"></path></svg>'
|
||||
),
|
||||
"class": "",
|
||||
},
|
||||
],
|
||||
|
||||
@@ -1,7 +1,43 @@
|
||||
``customwebhookbot.py``
|
||||
=======================
|
||||
|
||||
.. literalinclude:: ../../examples/customwebhookbot.py
|
||||
:language: python
|
||||
:linenos:
|
||||
This example is available for different web frameworks.
|
||||
You can select your preferred framework by opening one of the tabs above the code example.
|
||||
|
||||
.. hint::
|
||||
|
||||
The following examples show how different Python web frameworks can be used alongside PTB.
|
||||
This can be useful for two use cases:
|
||||
|
||||
1. For extending the functionality of your existing bot to handling updates of external services
|
||||
2. For extending the functionality of your exisiting web application to also include chat bot functionality
|
||||
|
||||
How the PTB and web framework components of the examples below are viewed surely depends on which use case one has in mind.
|
||||
We are fully aware that a combination of PTB with web frameworks will always mean finding a tradeoff between usability and best practices for both PTB and the web framework and these examples are certainly far from optimal solutions.
|
||||
Please understand them as starting points and use your expertise of the web framework of your choosing to build up on them.
|
||||
You are of course also very welcome to help improve these examples!
|
||||
|
||||
.. tab:: ``starlette``
|
||||
|
||||
.. literalinclude:: ../../examples/customwebhookbot/starlettebot.py
|
||||
:language: python
|
||||
:linenos:
|
||||
|
||||
.. tab:: ``flask``
|
||||
|
||||
.. literalinclude:: ../../examples/customwebhookbot/flaskbot.py
|
||||
:language: python
|
||||
:linenos:
|
||||
|
||||
.. tab:: ``quart``
|
||||
|
||||
.. literalinclude:: ../../examples/customwebhookbot/quartbot.py
|
||||
:language: python
|
||||
:linenos:
|
||||
|
||||
.. tab:: ``Django``
|
||||
|
||||
.. literalinclude:: ../../examples/customwebhookbot/djangobot.py
|
||||
:language: python
|
||||
:linenos:
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
.. tip::
|
||||
When combining ``python-telegram-bot`` with other :mod:`asyncio` based frameworks, using this
|
||||
method is likely not the best choice, as it blocks the event loop until it receives a stop
|
||||
signal as described above.
|
||||
Instead, you can manually call the methods listed below to start and shut down the application
|
||||
and the :attr:`~telegram.ext.Application.updater`.
|
||||
Keeping the event loop running and listening for a stop signal is then up to you.
|
||||
* When combining ``python-telegram-bot`` with other :mod:`asyncio` based frameworks, using this
|
||||
method is likely not the best choice, as it blocks the event loop until it receives a stop
|
||||
signal as described above.
|
||||
Instead, you can manually call the methods listed below to start and shut down the application
|
||||
and the :attr:`~telegram.ext.Application.updater`.
|
||||
Keeping the event loop running and listening for a stop signal is then up to you.
|
||||
* To gracefully stop the execution of this method from within a handler, job or error callback,
|
||||
use :meth:`~telegram.ext.Application.stop_running`.
|
||||
@@ -237,7 +237,7 @@
|
||||
- Used for setting the keywords of a sticker
|
||||
* - :meth:`~telegram.Bot.set_sticker_mask_position`
|
||||
- Used for setting the mask position of a mask sticker
|
||||
* - :meth:`~telegram.Bot.set_sticker_set_thumb`
|
||||
* - :meth:`~telegram.Bot.set_sticker_set_thumbnail`
|
||||
- Used for setting the thumbnail of a sticker set
|
||||
* - :meth:`~telegram.Bot.set_custom_emoji_sticker_set_thumbnail`
|
||||
- Used for setting the thumbnail of a custom emoji sticker set
|
||||
@@ -328,6 +328,8 @@
|
||||
- Used to reopen the general topic
|
||||
* - :meth:`~telegram.Bot.unpin_all_forum_topic_messages`
|
||||
- Used to unpin all messages in a forum topic
|
||||
* - :meth:`~telegram.Bot.unpin_all_general_forum_topic_messages`
|
||||
- Used to unpin all messages in the general forum topic
|
||||
|
||||
.. raw:: html
|
||||
|
||||
|
||||
@@ -79,6 +79,7 @@ Available Types
|
||||
telegram.replykeyboardmarkup
|
||||
telegram.replykeyboardremove
|
||||
telegram.sentwebappmessage
|
||||
telegram.story
|
||||
telegram.switchinlinequerychosenchat
|
||||
telegram.telegramobject
|
||||
telegram.update
|
||||
|
||||
@@ -4,4 +4,4 @@ Bot
|
||||
.. autoclass:: telegram.Bot
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:special-members: __reduce__, __deepcopy__
|
||||
:special-members: __repr__, __reduce__, __deepcopy__
|
||||
@@ -4,3 +4,4 @@ Application
|
||||
.. autoclass:: telegram.ext.Application
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:special-members: __repr__
|
||||
|
||||
@@ -4,3 +4,4 @@ BaseHandler
|
||||
.. autoclass:: telegram.ext.BaseHandler
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:special-members: __repr__
|
||||
|
||||
@@ -4,3 +4,4 @@ ConversationHandler
|
||||
.. autoclass:: telegram.ext.ConversationHandler
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:special-members: __repr__
|
||||
|
||||
@@ -4,3 +4,4 @@ ExtBot
|
||||
.. autoclass:: telegram.ext.ExtBot
|
||||
:show-inheritance:
|
||||
:members: insert_callback_data, defaults, rate_limiter, initialize, shutdown, callback_data_cache
|
||||
:special-members: __repr__
|
||||
|
||||
@@ -4,4 +4,4 @@ Job
|
||||
.. autoclass:: telegram.ext.Job
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:special-members: __call__
|
||||
:special-members: __call__, __repr__
|
||||
|
||||
@@ -4,3 +4,4 @@ JobQueue
|
||||
.. autoclass:: telegram.ext.JobQueue
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:special-members: __repr__
|
||||
|
||||
@@ -4,3 +4,4 @@ Updater
|
||||
.. autoclass:: telegram.ext.Updater
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:special-members: __repr__
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
Story
|
||||
=====
|
||||
|
||||
.. autoclass:: telegram.Story
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -14,10 +14,6 @@
|
||||
|
||||
.. |thumbdocstringnopath| replace:: |thumbdocstringbase| |uploadinputnopath|
|
||||
|
||||
.. |thumbargumentdeprecation| replace:: As of Bot API 6.6 this argument is deprecated in favor of
|
||||
|
||||
.. |thumbattributedeprecation| replace:: As of Bot API 6.6 this attribute is deprecated in favor of
|
||||
|
||||
.. |editreplymarkup| replace:: It is currently only possible to edit messages without :attr:`telegram.Message.reply_markup` or with inline keyboards.
|
||||
|
||||
.. |toapikwargsbase| replace:: These arguments are also considered by :meth:`~telegram.TelegramObject.to_dict` and :meth:`~telegram.TelegramObject.to_json`, i.e. when passing objects to Telegram. Passing them to Telegram is however not guaranteed to work for all kinds of objects, e.g. this will fail for objects that can not directly be JSON serialized.
|
||||
@@ -57,3 +53,11 @@
|
||||
.. |captionentitiesattr| replace:: Tuple of special entities that appear in the caption, which can be specified instead of ``parse_mode``.
|
||||
|
||||
.. |datetime_localization| replace:: The default timezone of the bot is used for localization, which is UTC unless :attr:`telegram.ext.Defaults.tzinfo` is used.
|
||||
|
||||
.. |post_methods_note| replace:: If you implement custom logic that implies that you will **not** be using :class:`~telegram.ext.Application`'s methods :meth:`~telegram.ext.Application.run_polling` or :meth:`~telegram.ext.Application.run_webhook` to run your application (like it's done in `Custom Webhook Bot Example <https://docs.python-telegram-bot.org/en/stable/examples.customwebhookbot.html>`__), the callback you set in this method **will not be called automatically**. So instead of setting a callback with this method, you have to explicitly ``await`` the function that you want to run at this stage of your application's life (in the `example mentioned above <https://docs.python-telegram-bot.org/en/stable/examples.customwebhookbot.html>`__, that would be in ``async with application`` context manager).
|
||||
|
||||
.. |removed_thumb_note| replace:: Removed the deprecated argument and attribute ``thumb``.
|
||||
|
||||
.. |removed_thumb_url_note| replace:: Removed the deprecated argument and attribute ``thumb_url``.
|
||||
|
||||
.. |removed_thumb_wildcard_note| replace:: Removed the deprecated arguments and attributes ``thumb_*``.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=unused-argument, wrong-import-position
|
||||
# pylint: disable=unused-argument
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""This example showcases how PTBs "arbitrary callback data" feature can be used.
|
||||
@@ -14,19 +14,6 @@ To use arbitrary callback data, you must install PTB via
|
||||
import logging
|
||||
from typing import List, Tuple, cast
|
||||
|
||||
from telegram import __version__ as TG_VER
|
||||
|
||||
try:
|
||||
from telegram import __version_info__
|
||||
except ImportError:
|
||||
__version_info__ = (0, 0, 0, 0, 0) # type: ignore[assignment]
|
||||
|
||||
if __version_info__ < (20, 0, 0, "alpha", 1):
|
||||
raise RuntimeError(
|
||||
f"This example is not compatible with your current PTB version {TG_VER}. To view the "
|
||||
f"{TG_VER} version of this example, "
|
||||
f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html"
|
||||
)
|
||||
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
|
||||
from telegram.ext import (
|
||||
Application,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=unused-argument, wrong-import-position
|
||||
# pylint: disable=unused-argument
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""
|
||||
@@ -14,19 +14,6 @@ bot.
|
||||
import logging
|
||||
from typing import Optional, Tuple
|
||||
|
||||
from telegram import __version__ as TG_VER
|
||||
|
||||
try:
|
||||
from telegram import __version_info__
|
||||
except ImportError:
|
||||
__version_info__ = (0, 0, 0, 0, 0) # type: ignore[assignment]
|
||||
|
||||
if __version_info__ < (20, 0, 0, "alpha", 1):
|
||||
raise RuntimeError(
|
||||
f"This example is not compatible with your current PTB version {TG_VER}. To view the "
|
||||
f"{TG_VER} version of this example, "
|
||||
f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html"
|
||||
)
|
||||
from telegram import Chat, ChatMember, ChatMemberUpdated, Update
|
||||
from telegram.constants import ParseMode
|
||||
from telegram.ext import (
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=unused-argument, wrong-import-position
|
||||
# pylint: disable=unused-argument
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""
|
||||
@@ -14,19 +14,6 @@ import logging
|
||||
from collections import defaultdict
|
||||
from typing import DefaultDict, Optional, Set
|
||||
|
||||
from telegram import __version__ as TG_VER
|
||||
|
||||
try:
|
||||
from telegram import __version_info__
|
||||
except ImportError:
|
||||
__version_info__ = (0, 0, 0, 0, 0) # type: ignore[assignment]
|
||||
|
||||
if __version_info__ < (20, 0, 0, "alpha", 1):
|
||||
raise RuntimeError(
|
||||
f"This example is not compatible with your current PTB version {TG_VER}. To view the "
|
||||
f"{TG_VER} version of this example, "
|
||||
f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html"
|
||||
)
|
||||
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
|
||||
from telegram.constants import ParseMode
|
||||
from telegram.ext import (
|
||||
@@ -128,8 +115,7 @@ async def count_click(update: Update, context: CustomContext) -> None:
|
||||
async def print_users(update: Update, context: CustomContext) -> None:
|
||||
"""Show which users have been using this bot."""
|
||||
await update.message.reply_text(
|
||||
"The following user IDs have used this bot: "
|
||||
f'{", ".join(map(str, context.bot_user_ids))}'
|
||||
f"The following user IDs have used this bot: {', '.join(map(str, context.bot_user_ids))}"
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=unused-argument, wrong-import-position
|
||||
# pylint: disable=unused-argument
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""
|
||||
@@ -16,19 +16,6 @@ bot.
|
||||
|
||||
import logging
|
||||
|
||||
from telegram import __version__ as TG_VER
|
||||
|
||||
try:
|
||||
from telegram import __version_info__
|
||||
except ImportError:
|
||||
__version_info__ = (0, 0, 0, 0, 0) # type: ignore[assignment]
|
||||
|
||||
if __version_info__ < (20, 0, 0, "alpha", 5):
|
||||
raise RuntimeError(
|
||||
f"This example is not compatible with your current PTB version {TG_VER}. To view the "
|
||||
f"{TG_VER} version of this example, "
|
||||
f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html"
|
||||
)
|
||||
from telegram import ReplyKeyboardMarkup, ReplyKeyboardRemove, Update
|
||||
from telegram.ext import (
|
||||
Application,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=unused-argument, wrong-import-position
|
||||
# pylint: disable=unused-argument
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""
|
||||
@@ -17,19 +17,6 @@ bot.
|
||||
import logging
|
||||
from typing import Dict
|
||||
|
||||
from telegram import __version__ as TG_VER
|
||||
|
||||
try:
|
||||
from telegram import __version_info__
|
||||
except ImportError:
|
||||
__version_info__ = (0, 0, 0, 0, 0) # type: ignore[assignment]
|
||||
|
||||
if __version_info__ < (20, 0, 0, "alpha", 1):
|
||||
raise RuntimeError(
|
||||
f"This example is not compatible with your current PTB version {TG_VER}. To view the "
|
||||
f"{TG_VER} version of this example, "
|
||||
f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html"
|
||||
)
|
||||
from telegram import ReplyKeyboardMarkup, ReplyKeyboardRemove, Update
|
||||
from telegram.ext import (
|
||||
Application,
|
||||
|
||||
@@ -0,0 +1,179 @@
|
||||
#!/usr/bin/env python
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
# pylint: disable=import-error,unused-argument
|
||||
"""
|
||||
Simple example of a bot that uses a custom webhook setup and handles custom updates.
|
||||
For the custom webhook setup, the libraries `Django` and `uvicorn` are used. Please
|
||||
install them as `pip install Django~=4.2.4 uvicorn~=0.23.2`.
|
||||
Note that any other `asyncio` based web server framework can be used for a custom webhook setup
|
||||
just as well.
|
||||
|
||||
Usage:
|
||||
Set bot Token, URL, admin CHAT_ID and PORT after the imports.
|
||||
You may also need to change the `listen` value in the uvicorn configuration to match your setup.
|
||||
Press Ctrl-C on the command line or send a signal to the process to stop the bot.
|
||||
"""
|
||||
import asyncio
|
||||
import html
|
||||
import json
|
||||
import logging
|
||||
from dataclasses import dataclass
|
||||
from uuid import uuid4
|
||||
|
||||
import uvicorn
|
||||
from django.conf import settings
|
||||
from django.core.asgi import get_asgi_application
|
||||
from django.http import HttpRequest, HttpResponse, HttpResponseBadRequest
|
||||
from django.urls import path
|
||||
|
||||
from telegram import Update
|
||||
from telegram.constants import ParseMode
|
||||
from telegram.ext import (
|
||||
Application,
|
||||
CallbackContext,
|
||||
CommandHandler,
|
||||
ContextTypes,
|
||||
ExtBot,
|
||||
TypeHandler,
|
||||
)
|
||||
|
||||
# Enable logging
|
||||
logging.basicConfig(
|
||||
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", level=logging.INFO
|
||||
)
|
||||
# set higher logging level for httpx to avoid all GET and POST requests being logged
|
||||
logging.getLogger("httpx").setLevel(logging.WARNING)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Define configuration constants
|
||||
URL = "https://domain.tld"
|
||||
ADMIN_CHAT_ID = 123456
|
||||
PORT = 8000
|
||||
TOKEN = "123:ABC" # nosec B105
|
||||
|
||||
|
||||
@dataclass
|
||||
class WebhookUpdate:
|
||||
"""Simple dataclass to wrap a custom update type"""
|
||||
|
||||
user_id: int
|
||||
payload: str
|
||||
|
||||
|
||||
class CustomContext(CallbackContext[ExtBot, dict, dict, dict]):
|
||||
"""
|
||||
Custom CallbackContext class that makes `user_data` available for updates of type
|
||||
`WebhookUpdate`.
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def from_update(
|
||||
cls,
|
||||
update: object,
|
||||
application: "Application",
|
||||
) -> "CustomContext":
|
||||
if isinstance(update, WebhookUpdate):
|
||||
return cls(application=application, user_id=update.user_id)
|
||||
return super().from_update(update, application)
|
||||
|
||||
|
||||
async def start(update: Update, context: CustomContext) -> None:
|
||||
"""Display a message with instructions on how to use this bot."""
|
||||
payload_url = html.escape(f"{URL}/submitpayload?user_id=<your user id>&payload=<payload>")
|
||||
text = (
|
||||
f"To check if the bot is still running, call <code>{URL}/healthcheck</code>.\n\n"
|
||||
f"To post a custom update, call <code>{payload_url}</code>."
|
||||
)
|
||||
await update.message.reply_html(text=text)
|
||||
|
||||
|
||||
async def webhook_update(update: WebhookUpdate, context: CustomContext) -> None:
|
||||
"""Handle custom updates."""
|
||||
chat_member = await context.bot.get_chat_member(chat_id=update.user_id, user_id=update.user_id)
|
||||
payloads = context.user_data.setdefault("payloads", [])
|
||||
payloads.append(update.payload)
|
||||
combined_payloads = "</code>\n• <code>".join(payloads)
|
||||
text = (
|
||||
f"The user {chat_member.user.mention_html()} has sent a new payload. "
|
||||
f"So far they have sent the following payloads: \n\n• <code>{combined_payloads}</code>"
|
||||
)
|
||||
await context.bot.send_message(chat_id=ADMIN_CHAT_ID, text=text, parse_mode=ParseMode.HTML)
|
||||
|
||||
|
||||
async def telegram(request: HttpRequest) -> HttpResponse:
|
||||
"""Handle incoming Telegram updates by putting them into the `update_queue`"""
|
||||
await ptb_application.update_queue.put(
|
||||
Update.de_json(data=json.loads(request.body), bot=ptb_application.bot)
|
||||
)
|
||||
return HttpResponse()
|
||||
|
||||
|
||||
async def custom_updates(request: HttpRequest) -> HttpResponse:
|
||||
"""
|
||||
Handle incoming webhook updates by also putting them into the `update_queue` if
|
||||
the required parameters were passed correctly.
|
||||
"""
|
||||
try:
|
||||
user_id = int(request.GET["user_id"])
|
||||
payload = request.GET["payload"]
|
||||
except KeyError:
|
||||
return HttpResponseBadRequest(
|
||||
"Please pass both `user_id` and `payload` as query parameters.",
|
||||
)
|
||||
except ValueError:
|
||||
return HttpResponseBadRequest("The `user_id` must be a string!")
|
||||
|
||||
await ptb_application.update_queue.put(WebhookUpdate(user_id=user_id, payload=payload))
|
||||
return HttpResponse()
|
||||
|
||||
|
||||
async def health(_: HttpRequest) -> HttpResponse:
|
||||
"""For the health endpoint, reply with a simple plain text message."""
|
||||
return HttpResponse("The bot is still running fine :)")
|
||||
|
||||
|
||||
# Set up PTB application and a web application for handling the incoming requests.
|
||||
|
||||
context_types = ContextTypes(context=CustomContext)
|
||||
# Here we set updater to None because we want our custom webhook server to handle the updates
|
||||
# and hence we don't need an Updater instance
|
||||
ptb_application = (
|
||||
Application.builder().token(TOKEN).updater(None).context_types(context_types).build()
|
||||
)
|
||||
|
||||
# register handlers
|
||||
ptb_application.add_handler(CommandHandler("start", start))
|
||||
ptb_application.add_handler(TypeHandler(type=WebhookUpdate, callback=webhook_update))
|
||||
|
||||
urlpatterns = [
|
||||
path("telegram", telegram, name="Telegram updates"),
|
||||
path("submitpayload", custom_updates, name="custom updates"),
|
||||
path("healthcheck", health, name="health check"),
|
||||
]
|
||||
settings.configure(ROOT_URLCONF=__name__, SECRET_KEY=uuid4().hex)
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
"""Finalize configuration and run the applications."""
|
||||
webserver = uvicorn.Server(
|
||||
config=uvicorn.Config(
|
||||
app=get_asgi_application(),
|
||||
port=PORT,
|
||||
use_colors=False,
|
||||
host="127.0.0.1",
|
||||
)
|
||||
)
|
||||
|
||||
# Pass webhook settings to telegram
|
||||
await ptb_application.bot.set_webhook(url=f"{URL}/telegram", allowed_updates=Update.ALL_TYPES)
|
||||
|
||||
# Run application and webserver together
|
||||
async with ptb_application:
|
||||
await ptb_application.start()
|
||||
await webserver.serve()
|
||||
await ptb_application.stop()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,170 @@
|
||||
#!/usr/bin/env python
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
# pylint: disable=import-error,unused-argument
|
||||
"""
|
||||
Simple example of a bot that uses a custom webhook setup and handles custom updates.
|
||||
For the custom webhook setup, the libraries `flask`, `asgiref` and `uvicorn` are used. Please
|
||||
install them as `pip install flask[async]~=2.3.2 uvicorn~=0.23.2 asgiref~=3.7.2`.
|
||||
Note that any other `asyncio` based web server framework can be used for a custom webhook setup
|
||||
just as well.
|
||||
|
||||
Usage:
|
||||
Set bot Token, URL, admin CHAT_ID and PORT after the imports.
|
||||
You may also need to change the `listen` value in the uvicorn configuration to match your setup.
|
||||
Press Ctrl-C on the command line or send a signal to the process to stop the bot.
|
||||
"""
|
||||
import asyncio
|
||||
import html
|
||||
import logging
|
||||
from dataclasses import dataclass
|
||||
from http import HTTPStatus
|
||||
|
||||
import uvicorn
|
||||
from asgiref.wsgi import WsgiToAsgi
|
||||
from flask import Flask, Response, abort, make_response, request
|
||||
|
||||
from telegram import Update
|
||||
from telegram.constants import ParseMode
|
||||
from telegram.ext import (
|
||||
Application,
|
||||
CallbackContext,
|
||||
CommandHandler,
|
||||
ContextTypes,
|
||||
ExtBot,
|
||||
TypeHandler,
|
||||
)
|
||||
|
||||
# Enable logging
|
||||
logging.basicConfig(
|
||||
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", level=logging.INFO
|
||||
)
|
||||
# set higher logging level for httpx to avoid all GET and POST requests being logged
|
||||
logging.getLogger("httpx").setLevel(logging.WARNING)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Define configuration constants
|
||||
URL = "https://domain.tld"
|
||||
ADMIN_CHAT_ID = 123456
|
||||
PORT = 8000
|
||||
TOKEN = "123:ABC" # nosec B105
|
||||
|
||||
|
||||
@dataclass
|
||||
class WebhookUpdate:
|
||||
"""Simple dataclass to wrap a custom update type"""
|
||||
|
||||
user_id: int
|
||||
payload: str
|
||||
|
||||
|
||||
class CustomContext(CallbackContext[ExtBot, dict, dict, dict]):
|
||||
"""
|
||||
Custom CallbackContext class that makes `user_data` available for updates of type
|
||||
`WebhookUpdate`.
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def from_update(
|
||||
cls,
|
||||
update: object,
|
||||
application: "Application",
|
||||
) -> "CustomContext":
|
||||
if isinstance(update, WebhookUpdate):
|
||||
return cls(application=application, user_id=update.user_id)
|
||||
return super().from_update(update, application)
|
||||
|
||||
|
||||
async def start(update: Update, context: CustomContext) -> None:
|
||||
"""Display a message with instructions on how to use this bot."""
|
||||
payload_url = html.escape(f"{URL}/submitpayload?user_id=<your user id>&payload=<payload>")
|
||||
text = (
|
||||
f"To check if the bot is still running, call <code>{URL}/healthcheck</code>.\n\n"
|
||||
f"To post a custom update, call <code>{payload_url}</code>."
|
||||
)
|
||||
await update.message.reply_html(text=text)
|
||||
|
||||
|
||||
async def webhook_update(update: WebhookUpdate, context: CustomContext) -> None:
|
||||
"""Handle custom updates."""
|
||||
chat_member = await context.bot.get_chat_member(chat_id=update.user_id, user_id=update.user_id)
|
||||
payloads = context.user_data.setdefault("payloads", [])
|
||||
payloads.append(update.payload)
|
||||
combined_payloads = "</code>\n• <code>".join(payloads)
|
||||
text = (
|
||||
f"The user {chat_member.user.mention_html()} has sent a new payload. "
|
||||
f"So far they have sent the following payloads: \n\n• <code>{combined_payloads}</code>"
|
||||
)
|
||||
await context.bot.send_message(chat_id=ADMIN_CHAT_ID, text=text, parse_mode=ParseMode.HTML)
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
"""Set up PTB application and a web application for handling the incoming requests."""
|
||||
context_types = ContextTypes(context=CustomContext)
|
||||
# Here we set updater to None because we want our custom webhook server to handle the updates
|
||||
# and hence we don't need an Updater instance
|
||||
application = (
|
||||
Application.builder().token(TOKEN).updater(None).context_types(context_types).build()
|
||||
)
|
||||
|
||||
# register handlers
|
||||
application.add_handler(CommandHandler("start", start))
|
||||
application.add_handler(TypeHandler(type=WebhookUpdate, callback=webhook_update))
|
||||
|
||||
# Pass webhook settings to telegram
|
||||
await application.bot.set_webhook(url=f"{URL}/telegram", allowed_updates=Update.ALL_TYPES)
|
||||
|
||||
# Set up webserver
|
||||
flask_app = Flask(__name__)
|
||||
|
||||
@flask_app.post("/telegram") # type: ignore[misc]
|
||||
async def telegram() -> Response:
|
||||
"""Handle incoming Telegram updates by putting them into the `update_queue`"""
|
||||
await application.update_queue.put(Update.de_json(data=request.json, bot=application.bot))
|
||||
return Response(status=HTTPStatus.OK)
|
||||
|
||||
@flask_app.route("/submitpayload", methods=["GET", "POST"]) # type: ignore[misc]
|
||||
async def custom_updates() -> Response:
|
||||
"""
|
||||
Handle incoming webhook updates by also putting them into the `update_queue` if
|
||||
the required parameters were passed correctly.
|
||||
"""
|
||||
try:
|
||||
user_id = int(request.args["user_id"])
|
||||
payload = request.args["payload"]
|
||||
except KeyError:
|
||||
abort(
|
||||
HTTPStatus.BAD_REQUEST,
|
||||
"Please pass both `user_id` and `payload` as query parameters.",
|
||||
)
|
||||
except ValueError:
|
||||
abort(HTTPStatus.BAD_REQUEST, "The `user_id` must be a string!")
|
||||
|
||||
await application.update_queue.put(WebhookUpdate(user_id=user_id, payload=payload))
|
||||
return Response(status=HTTPStatus.OK)
|
||||
|
||||
@flask_app.get("/healthcheck") # type: ignore[misc]
|
||||
async def health() -> Response:
|
||||
"""For the health endpoint, reply with a simple plain text message."""
|
||||
response = make_response("The bot is still running fine :)", HTTPStatus.OK)
|
||||
response.mimetype = "text/plain"
|
||||
return response
|
||||
|
||||
webserver = uvicorn.Server(
|
||||
config=uvicorn.Config(
|
||||
app=WsgiToAsgi(flask_app),
|
||||
port=PORT,
|
||||
use_colors=False,
|
||||
host="127.0.0.1",
|
||||
)
|
||||
)
|
||||
|
||||
# Run application and webserver together
|
||||
async with application:
|
||||
await application.start()
|
||||
await webserver.serve()
|
||||
await application.stop()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,171 @@
|
||||
#!/usr/bin/env python
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
# pylint: disable=import-error,unused-argument
|
||||
"""
|
||||
Simple example of a bot that uses a custom webhook setup and handles custom updates.
|
||||
For the custom webhook setup, the libraries `quart` and `uvicorn` are used. Please
|
||||
install them as `pip install quart~=0.18.4 uvicorn~=0.23.2`.
|
||||
Note that any other `asyncio` based web server framework can be used for a custom webhook setup
|
||||
just as well.
|
||||
|
||||
Usage:
|
||||
Set bot Token, URL, admin CHAT_ID and PORT after the imports.
|
||||
You may also need to change the `listen` value in the uvicorn configuration to match your setup.
|
||||
Press Ctrl-C on the command line or send a signal to the process to stop the bot.
|
||||
"""
|
||||
import asyncio
|
||||
import html
|
||||
import logging
|
||||
from dataclasses import dataclass
|
||||
from http import HTTPStatus
|
||||
|
||||
import uvicorn
|
||||
from quart import Quart, Response, abort, make_response, request
|
||||
|
||||
from telegram import Update
|
||||
from telegram.constants import ParseMode
|
||||
from telegram.ext import (
|
||||
Application,
|
||||
CallbackContext,
|
||||
CommandHandler,
|
||||
ContextTypes,
|
||||
ExtBot,
|
||||
TypeHandler,
|
||||
)
|
||||
|
||||
# Enable logging
|
||||
logging.basicConfig(
|
||||
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", level=logging.INFO
|
||||
)
|
||||
# set higher logging level for httpx to avoid all GET and POST requests being logged
|
||||
logging.getLogger("httpx").setLevel(logging.WARNING)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Define configuration constants
|
||||
URL = "https://domain.tld"
|
||||
ADMIN_CHAT_ID = 123456
|
||||
PORT = 8000
|
||||
TOKEN = "123:ABC" # nosec B105
|
||||
|
||||
|
||||
@dataclass
|
||||
class WebhookUpdate:
|
||||
"""Simple dataclass to wrap a custom update type"""
|
||||
|
||||
user_id: int
|
||||
payload: str
|
||||
|
||||
|
||||
class CustomContext(CallbackContext[ExtBot, dict, dict, dict]):
|
||||
"""
|
||||
Custom CallbackContext class that makes `user_data` available for updates of type
|
||||
`WebhookUpdate`.
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def from_update(
|
||||
cls,
|
||||
update: object,
|
||||
application: "Application",
|
||||
) -> "CustomContext":
|
||||
if isinstance(update, WebhookUpdate):
|
||||
return cls(application=application, user_id=update.user_id)
|
||||
return super().from_update(update, application)
|
||||
|
||||
|
||||
async def start(update: Update, context: CustomContext) -> None:
|
||||
"""Display a message with instructions on how to use this bot."""
|
||||
payload_url = html.escape(f"{URL}/submitpayload?user_id=<your user id>&payload=<payload>")
|
||||
text = (
|
||||
f"To check if the bot is still running, call <code>{URL}/healthcheck</code>.\n\n"
|
||||
f"To post a custom update, call <code>{payload_url}</code>."
|
||||
)
|
||||
await update.message.reply_html(text=text)
|
||||
|
||||
|
||||
async def webhook_update(update: WebhookUpdate, context: CustomContext) -> None:
|
||||
"""Handle custom updates."""
|
||||
chat_member = await context.bot.get_chat_member(chat_id=update.user_id, user_id=update.user_id)
|
||||
payloads = context.user_data.setdefault("payloads", [])
|
||||
payloads.append(update.payload)
|
||||
combined_payloads = "</code>\n• <code>".join(payloads)
|
||||
text = (
|
||||
f"The user {chat_member.user.mention_html()} has sent a new payload. "
|
||||
f"So far they have sent the following payloads: \n\n• <code>{combined_payloads}</code>"
|
||||
)
|
||||
await context.bot.send_message(chat_id=ADMIN_CHAT_ID, text=text, parse_mode=ParseMode.HTML)
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
"""Set up PTB application and a web application for handling the incoming requests."""
|
||||
context_types = ContextTypes(context=CustomContext)
|
||||
# Here we set updater to None because we want our custom webhook server to handle the updates
|
||||
# and hence we don't need an Updater instance
|
||||
application = (
|
||||
Application.builder().token(TOKEN).updater(None).context_types(context_types).build()
|
||||
)
|
||||
|
||||
# register handlers
|
||||
application.add_handler(CommandHandler("start", start))
|
||||
application.add_handler(TypeHandler(type=WebhookUpdate, callback=webhook_update))
|
||||
|
||||
# Pass webhook settings to telegram
|
||||
await application.bot.set_webhook(url=f"{URL}/telegram", allowed_updates=Update.ALL_TYPES)
|
||||
|
||||
# Set up webserver
|
||||
quart_app = Quart(__name__)
|
||||
|
||||
@quart_app.post("/telegram") # type: ignore[misc]
|
||||
async def telegram() -> Response:
|
||||
"""Handle incoming Telegram updates by putting them into the `update_queue`"""
|
||||
await application.update_queue.put(
|
||||
Update.de_json(data=await request.get_json(), bot=application.bot)
|
||||
)
|
||||
return Response(status=HTTPStatus.OK)
|
||||
|
||||
@quart_app.route("/submitpayload", methods=["GET", "POST"]) # type: ignore[misc]
|
||||
async def custom_updates() -> Response:
|
||||
"""
|
||||
Handle incoming webhook updates by also putting them into the `update_queue` if
|
||||
the required parameters were passed correctly.
|
||||
"""
|
||||
try:
|
||||
user_id = int(request.args["user_id"])
|
||||
payload = request.args["payload"]
|
||||
except KeyError:
|
||||
abort(
|
||||
HTTPStatus.BAD_REQUEST,
|
||||
"Please pass both `user_id` and `payload` as query parameters.",
|
||||
)
|
||||
except ValueError:
|
||||
abort(HTTPStatus.BAD_REQUEST, "The `user_id` must be a string!")
|
||||
|
||||
await application.update_queue.put(WebhookUpdate(user_id=user_id, payload=payload))
|
||||
return Response(status=HTTPStatus.OK)
|
||||
|
||||
@quart_app.get("/healthcheck") # type: ignore[misc]
|
||||
async def health() -> Response:
|
||||
"""For the health endpoint, reply with a simple plain text message."""
|
||||
response = await make_response("The bot is still running fine :)", HTTPStatus.OK)
|
||||
response.mimetype = "text/plain"
|
||||
return response
|
||||
|
||||
webserver = uvicorn.Server(
|
||||
config=uvicorn.Config(
|
||||
app=quart_app,
|
||||
port=PORT,
|
||||
use_colors=False,
|
||||
host="127.0.0.1",
|
||||
)
|
||||
)
|
||||
|
||||
# Run application and webserver together
|
||||
async with application:
|
||||
await application.start()
|
||||
await webserver.serve()
|
||||
await application.stop()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -1,15 +1,15 @@
|
||||
#!/usr/bin/env python
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
# pylint: disable=import-error,wrong-import-position
|
||||
# pylint: disable=import-error,unused-argument
|
||||
"""
|
||||
Simple example of a bot that uses a custom webhook setup and handles custom updates.
|
||||
For the custom webhook setup, the libraries `starlette` and `uvicorn` are used. Please install
|
||||
them as `pip install starlette~=0.20.0 uvicorn~=0.17.0`.
|
||||
them as `pip install starlette~=0.20.0 uvicorn~=0.23.2`.
|
||||
Note that any other `asyncio` based web server framework can be used for a custom webhook setup
|
||||
just as well.
|
||||
|
||||
Usage:
|
||||
Set bot token, url, admin chat_id and port at the start of the `main` function.
|
||||
Set bot Token, URL, admin CHAT_ID and PORT after the imports.
|
||||
You may also need to change the `listen` value in the uvicorn configuration to match your setup.
|
||||
Press Ctrl-C on the command line or send a signal to the process to stop the bot.
|
||||
"""
|
||||
@@ -25,20 +25,6 @@ from starlette.requests import Request
|
||||
from starlette.responses import PlainTextResponse, Response
|
||||
from starlette.routing import Route
|
||||
|
||||
from telegram import __version__ as TG_VER
|
||||
|
||||
try:
|
||||
from telegram import __version_info__
|
||||
except ImportError:
|
||||
__version_info__ = (0, 0, 0, 0, 0) # type: ignore[assignment]
|
||||
|
||||
if __version_info__ < (20, 0, 0, "alpha", 1):
|
||||
raise RuntimeError(
|
||||
f"This example is not compatible with your current PTB version {TG_VER}. To view the "
|
||||
f"{TG_VER} version of this example, "
|
||||
f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html"
|
||||
)
|
||||
|
||||
from telegram import Update
|
||||
from telegram.constants import ParseMode
|
||||
from telegram.ext import (
|
||||
@@ -59,6 +45,12 @@ logging.getLogger("httpx").setLevel(logging.WARNING)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Define configuration constants
|
||||
URL = "https://domain.tld"
|
||||
ADMIN_CHAT_ID = 123456
|
||||
PORT = 8000
|
||||
TOKEN = "123:ABC" # nosec B105
|
||||
|
||||
|
||||
@dataclass
|
||||
class WebhookUpdate:
|
||||
@@ -87,17 +79,16 @@ class CustomContext(CallbackContext[ExtBot, dict, dict, dict]):
|
||||
|
||||
async def start(update: Update, context: CustomContext) -> None:
|
||||
"""Display a message with instructions on how to use this bot."""
|
||||
url = context.bot_data["url"]
|
||||
payload_url = html.escape(f"{url}/submitpayload?user_id=<your user id>&payload=<payload>")
|
||||
payload_url = html.escape(f"{URL}/submitpayload?user_id=<your user id>&payload=<payload>")
|
||||
text = (
|
||||
f"To check if the bot is still running, call <code>{url}/healthcheck</code>.\n\n"
|
||||
f"To check if the bot is still running, call <code>{URL}/healthcheck</code>.\n\n"
|
||||
f"To post a custom update, call <code>{payload_url}</code>."
|
||||
)
|
||||
await update.message.reply_html(text=text)
|
||||
|
||||
|
||||
async def webhook_update(update: WebhookUpdate, context: CustomContext) -> None:
|
||||
"""Callback that handles the custom updates."""
|
||||
"""Handle custom updates."""
|
||||
chat_member = await context.bot.get_chat_member(chat_id=update.user_id, user_id=update.user_id)
|
||||
payloads = context.user_data.setdefault("payloads", [])
|
||||
payloads.append(update.payload)
|
||||
@@ -106,33 +97,24 @@ async def webhook_update(update: WebhookUpdate, context: CustomContext) -> None:
|
||||
f"The user {chat_member.user.mention_html()} has sent a new payload. "
|
||||
f"So far they have sent the following payloads: \n\n• <code>{combined_payloads}</code>"
|
||||
)
|
||||
await context.bot.send_message(
|
||||
chat_id=context.bot_data["admin_chat_id"], text=text, parse_mode=ParseMode.HTML
|
||||
)
|
||||
await context.bot.send_message(chat_id=ADMIN_CHAT_ID, text=text, parse_mode=ParseMode.HTML)
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
"""Set up the application and a custom webserver."""
|
||||
url = "https://domain.tld"
|
||||
admin_chat_id = 123456
|
||||
port = 8000
|
||||
|
||||
"""Set up PTB application and a web application for handling the incoming requests."""
|
||||
context_types = ContextTypes(context=CustomContext)
|
||||
# Here we set updater to None because we want our custom webhook server to handle the updates
|
||||
# and hence we don't need an Updater instance
|
||||
application = (
|
||||
Application.builder().token("TOKEN").updater(None).context_types(context_types).build()
|
||||
Application.builder().token(TOKEN).updater(None).context_types(context_types).build()
|
||||
)
|
||||
# save the values in `bot_data` such that we may easily access them in the callbacks
|
||||
application.bot_data["url"] = url
|
||||
application.bot_data["admin_chat_id"] = admin_chat_id
|
||||
|
||||
# register handlers
|
||||
application.add_handler(CommandHandler("start", start))
|
||||
application.add_handler(TypeHandler(type=WebhookUpdate, callback=webhook_update))
|
||||
|
||||
# Pass webhook settings to telegram
|
||||
await application.bot.set_webhook(url=f"{url}/telegram", allowed_updates=Update.ALL_TYPES)
|
||||
await application.bot.set_webhook(url=f"{URL}/telegram", allowed_updates=Update.ALL_TYPES)
|
||||
|
||||
# Set up webserver
|
||||
async def telegram(request: Request) -> Response:
|
||||
@@ -178,7 +160,7 @@ async def main() -> None:
|
||||
webserver = uvicorn.Server(
|
||||
config=uvicorn.Config(
|
||||
app=starlette_app,
|
||||
port=port,
|
||||
port=PORT,
|
||||
use_colors=False,
|
||||
host="127.0.0.1",
|
||||
)
|
||||
+2
-16
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=unused-argument, wrong-import-position
|
||||
# pylint: disable=unused-argument
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""Bot that explains Telegram's "Deep Linking Parameters" functionality.
|
||||
@@ -20,19 +20,6 @@ bot.
|
||||
|
||||
import logging
|
||||
|
||||
from telegram import __version__ as TG_VER
|
||||
|
||||
try:
|
||||
from telegram import __version_info__
|
||||
except ImportError:
|
||||
__version_info__ = (0, 0, 0, 0, 0) # type: ignore[assignment]
|
||||
|
||||
if __version_info__ < (20, 0, 0, "alpha", 1):
|
||||
raise RuntimeError(
|
||||
f"This example is not compatible with your current PTB version {TG_VER}. To view the "
|
||||
f"{TG_VER} version of this example, "
|
||||
f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html"
|
||||
)
|
||||
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update, helpers
|
||||
from telegram.constants import ParseMode
|
||||
from telegram.ext import Application, CallbackQueryHandler, CommandHandler, ContextTypes, filters
|
||||
@@ -70,8 +57,7 @@ async def deep_linked_level_1(update: Update, context: ContextTypes.DEFAULT_TYPE
|
||||
bot = context.bot
|
||||
url = helpers.create_deep_linked_url(bot.username, SO_COOL)
|
||||
text = (
|
||||
"Awesome, you just accessed hidden functionality! "
|
||||
"Now let's get back to the private chat."
|
||||
"Awesome, you just accessed hidden functionality! Now let's get back to the private chat."
|
||||
)
|
||||
keyboard = InlineKeyboardMarkup.from_button(
|
||||
InlineKeyboardButton(text="Continue here!", url=url)
|
||||
|
||||
+1
-14
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=unused-argument, wrong-import-position
|
||||
# pylint: disable=unused-argument
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""
|
||||
@@ -17,19 +17,6 @@ bot.
|
||||
|
||||
import logging
|
||||
|
||||
from telegram import __version__ as TG_VER
|
||||
|
||||
try:
|
||||
from telegram import __version_info__
|
||||
except ImportError:
|
||||
__version_info__ = (0, 0, 0, 0, 0) # type: ignore[assignment]
|
||||
|
||||
if __version_info__ < (20, 0, 0, "alpha", 1):
|
||||
raise RuntimeError(
|
||||
f"This example is not compatible with your current PTB version {TG_VER}. To view the "
|
||||
f"{TG_VER} version of this example, "
|
||||
f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html"
|
||||
)
|
||||
from telegram import ForceReply, Update
|
||||
from telegram.ext import Application, CommandHandler, ContextTypes, MessageHandler, filters
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=unused-argument, wrong-import-position
|
||||
# pylint: disable=unused-argument
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""This is a very simple example on how one could implement a custom error handler."""
|
||||
@@ -8,19 +8,6 @@ import json
|
||||
import logging
|
||||
import traceback
|
||||
|
||||
from telegram import __version__ as TG_VER
|
||||
|
||||
try:
|
||||
from telegram import __version_info__
|
||||
except ImportError:
|
||||
__version_info__ = (0, 0, 0, 0, 0) # type: ignore[assignment]
|
||||
|
||||
if __version_info__ < (20, 0, 0, "alpha", 1):
|
||||
raise RuntimeError(
|
||||
f"This example is not compatible with your current PTB version {TG_VER}. To view the "
|
||||
f"{TG_VER} version of this example, "
|
||||
f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html"
|
||||
)
|
||||
from telegram import Update
|
||||
from telegram.constants import ParseMode
|
||||
from telegram.ext import Application, CommandHandler, ContextTypes
|
||||
@@ -53,7 +40,7 @@ async def error_handler(update: object, context: ContextTypes.DEFAULT_TYPE) -> N
|
||||
# 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"
|
||||
"An exception was raised while handling an update\n"
|
||||
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"
|
||||
|
||||
+1
-14
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=unused-argument, wrong-import-position
|
||||
# pylint: disable=unused-argument
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""
|
||||
@@ -18,19 +18,6 @@ import logging
|
||||
from html import escape
|
||||
from uuid import uuid4
|
||||
|
||||
from telegram import __version__ as TG_VER
|
||||
|
||||
try:
|
||||
from telegram import __version_info__
|
||||
except ImportError:
|
||||
__version_info__ = (0, 0, 0, 0, 0) # type: ignore[assignment]
|
||||
|
||||
if __version_info__ < (20, 0, 0, "alpha", 1):
|
||||
raise RuntimeError(
|
||||
f"This example is not compatible with your current PTB version {TG_VER}. To view the "
|
||||
f"{TG_VER} version of this example, "
|
||||
f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html"
|
||||
)
|
||||
from telegram import InlineQueryResultArticle, InputTextMessageContent, Update
|
||||
from telegram.constants import ParseMode
|
||||
from telegram.ext import Application, CommandHandler, ContextTypes, InlineQueryHandler
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=unused-argument, wrong-import-position
|
||||
# pylint: disable=unused-argument
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""
|
||||
@@ -8,19 +8,6 @@ Basic example for a bot that uses inline keyboards. For an in-depth explanation,
|
||||
"""
|
||||
import logging
|
||||
|
||||
from telegram import __version__ as TG_VER
|
||||
|
||||
try:
|
||||
from telegram import __version_info__
|
||||
except ImportError:
|
||||
__version_info__ = (0, 0, 0, 0, 0) # type: ignore[assignment]
|
||||
|
||||
if __version_info__ < (20, 0, 0, "alpha", 1):
|
||||
raise RuntimeError(
|
||||
f"This example is not compatible with your current PTB version {TG_VER}. To view the "
|
||||
f"{TG_VER} version of this example, "
|
||||
f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html"
|
||||
)
|
||||
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
|
||||
from telegram.ext import Application, CallbackQueryHandler, CommandHandler, ContextTypes
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=unused-argument, wrong-import-position
|
||||
# pylint: disable=unused-argument
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""Simple inline keyboard bot with multiple CallbackQueryHandlers.
|
||||
@@ -16,19 +16,6 @@ Press Ctrl-C on the command line to stop the bot.
|
||||
"""
|
||||
import logging
|
||||
|
||||
from telegram import __version__ as TG_VER
|
||||
|
||||
try:
|
||||
from telegram import __version_info__
|
||||
except ImportError:
|
||||
__version_info__ = (0, 0, 0, 0, 0) # type: ignore[assignment]
|
||||
|
||||
if __version_info__ < (20, 0, 0, "alpha", 1):
|
||||
raise RuntimeError(
|
||||
f"This example is not compatible with your current PTB version {TG_VER}. To view the "
|
||||
f"{TG_VER} version of this example, "
|
||||
f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html"
|
||||
)
|
||||
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
|
||||
from telegram.ext import (
|
||||
Application,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=unused-argument, wrong-import-position
|
||||
# pylint: disable=unused-argument
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""
|
||||
@@ -17,19 +17,6 @@ bot.
|
||||
import logging
|
||||
from typing import Any, Dict, Tuple
|
||||
|
||||
from telegram import __version__ as TG_VER
|
||||
|
||||
try:
|
||||
from telegram import __version_info__
|
||||
except ImportError:
|
||||
__version_info__ = (0, 0, 0, 0, 0) # type: ignore[assignment]
|
||||
|
||||
if __version_info__ < (20, 0, 0, "alpha", 1):
|
||||
raise RuntimeError(
|
||||
f"This example is not compatible with your current PTB version {TG_VER}. To view the "
|
||||
f"{TG_VER} version of this example, "
|
||||
f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html"
|
||||
)
|
||||
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
|
||||
from telegram.ext import (
|
||||
Application,
|
||||
|
||||
+1
-14
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=unused-argument, wrong-import-position
|
||||
# pylint: disable=unused-argument
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""
|
||||
@@ -17,19 +17,6 @@ To use Telegram Passport, you must install PTB via
|
||||
import logging
|
||||
from pathlib import Path
|
||||
|
||||
from telegram import __version__ as TG_VER
|
||||
|
||||
try:
|
||||
from telegram import __version_info__
|
||||
except ImportError:
|
||||
__version_info__ = (0, 0, 0, 0, 0) # type: ignore[assignment]
|
||||
|
||||
if __version_info__ < (20, 0, 0, "alpha", 5):
|
||||
raise RuntimeError(
|
||||
f"This example is not compatible with your current PTB version {TG_VER}. To view the "
|
||||
f"{TG_VER} version of this example, "
|
||||
f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html"
|
||||
)
|
||||
from telegram import Update
|
||||
from telegram.ext import Application, ContextTypes, MessageHandler, filters
|
||||
|
||||
|
||||
+1
-14
@@ -1,24 +1,11 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=unused-argument, wrong-import-position
|
||||
# pylint: disable=unused-argument
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""Basic example for a bot that can receive payment from user."""
|
||||
|
||||
import logging
|
||||
|
||||
from telegram import __version__ as TG_VER
|
||||
|
||||
try:
|
||||
from telegram import __version_info__
|
||||
except ImportError:
|
||||
__version_info__ = (0, 0, 0, 0, 0) # type: ignore[assignment]
|
||||
|
||||
if __version_info__ < (20, 0, 0, "alpha", 1):
|
||||
raise RuntimeError(
|
||||
f"This example is not compatible with your current PTB version {TG_VER}. To view the "
|
||||
f"{TG_VER} version of this example, "
|
||||
f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html"
|
||||
)
|
||||
from telegram import LabeledPrice, ShippingOption, Update
|
||||
from telegram.ext import (
|
||||
Application,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=unused-argument, wrong-import-position
|
||||
# pylint: disable=unused-argument
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""
|
||||
@@ -17,19 +17,6 @@ bot.
|
||||
import logging
|
||||
from typing import Dict
|
||||
|
||||
from telegram import __version__ as TG_VER
|
||||
|
||||
try:
|
||||
from telegram import __version_info__
|
||||
except ImportError:
|
||||
__version_info__ = (0, 0, 0, 0, 0) # type: ignore[assignment]
|
||||
|
||||
if __version_info__ < (20, 0, 0, "alpha", 1):
|
||||
raise RuntimeError(
|
||||
f"This example is not compatible with your current PTB version {TG_VER}. To view the "
|
||||
f"{TG_VER} version of this example, "
|
||||
f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html"
|
||||
)
|
||||
from telegram import ReplyKeyboardMarkup, ReplyKeyboardRemove, Update
|
||||
from telegram.ext import (
|
||||
Application,
|
||||
@@ -72,7 +59,7 @@ async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
|
||||
if context.user_data:
|
||||
reply_text += (
|
||||
f" You already told me your {', '.join(context.user_data.keys())}. Why don't you "
|
||||
f"tell me something more about yourself? Or change anything I already know."
|
||||
"tell me something more about yourself? Or change anything I already know."
|
||||
)
|
||||
else:
|
||||
reply_text += (
|
||||
|
||||
+1
-14
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=unused-argument, wrong-import-position
|
||||
# pylint: disable=unused-argument
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""
|
||||
@@ -9,19 +9,6 @@ one the user sends the bot
|
||||
"""
|
||||
import logging
|
||||
|
||||
from telegram import __version__ as TG_VER
|
||||
|
||||
try:
|
||||
from telegram import __version_info__
|
||||
except ImportError:
|
||||
__version_info__ = (0, 0, 0, 0, 0) # type: ignore[assignment]
|
||||
|
||||
if __version_info__ < (20, 0, 0, "alpha", 1):
|
||||
raise RuntimeError(
|
||||
f"This example is not compatible with your current PTB version {TG_VER}. To view the "
|
||||
f"{TG_VER} version of this example, "
|
||||
f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html"
|
||||
)
|
||||
from telegram import (
|
||||
KeyboardButton,
|
||||
KeyboardButtonPollType,
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=wrong-import-position
|
||||
"""Simple Bot to reply to Telegram messages.
|
||||
|
||||
This is built on the API wrapper, see echobot.py to see the same example built
|
||||
@@ -11,19 +10,6 @@ import contextlib
|
||||
import logging
|
||||
from typing import NoReturn
|
||||
|
||||
from telegram import __version__ as TG_VER
|
||||
|
||||
try:
|
||||
from telegram import __version_info__
|
||||
except ImportError:
|
||||
__version_info__ = (0, 0, 0, 0, 0) # type: ignore[assignment] # type: ignore[assignment]
|
||||
|
||||
if __version_info__ < (20, 0, 0, "alpha", 1):
|
||||
raise RuntimeError(
|
||||
f"This example is not compatible with your current PTB version {TG_VER}. To view the "
|
||||
f"{TG_VER} version of this example, "
|
||||
f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html"
|
||||
)
|
||||
from telegram import Bot, Update
|
||||
from telegram.error import Forbidden, NetworkError
|
||||
|
||||
|
||||
+1
-14
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=unused-argument, wrong-import-position
|
||||
# pylint: disable=unused-argument
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""
|
||||
@@ -24,19 +24,6 @@ To use the JobQueue, you must install PTB via
|
||||
|
||||
import logging
|
||||
|
||||
from telegram import __version__ as TG_VER
|
||||
|
||||
try:
|
||||
from telegram import __version_info__
|
||||
except ImportError:
|
||||
__version_info__ = (0, 0, 0, 0, 0) # type: ignore[assignment]
|
||||
|
||||
if __version_info__ < (20, 0, 0, "alpha", 1):
|
||||
raise RuntimeError(
|
||||
f"This example is not compatible with your current PTB version {TG_VER}. To view the "
|
||||
f"{TG_VER} version of this example, "
|
||||
f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html"
|
||||
)
|
||||
from telegram import Update
|
||||
from telegram.ext import Application, CommandHandler, ContextTypes
|
||||
|
||||
|
||||
+5
-16
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=unused-argument,wrong-import-position
|
||||
# pylint: disable=unused-argument
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""
|
||||
@@ -11,19 +11,6 @@ require a bot token.
|
||||
import json
|
||||
import logging
|
||||
|
||||
from telegram import __version__ as TG_VER
|
||||
|
||||
try:
|
||||
from telegram import __version_info__
|
||||
except ImportError:
|
||||
__version_info__ = (0, 0, 0, 0, 0) # type: ignore[assignment]
|
||||
|
||||
if __version_info__ < (20, 0, 0, "alpha", 1):
|
||||
raise RuntimeError(
|
||||
f"This example is not compatible with your current PTB version {TG_VER}. To view the "
|
||||
f"{TG_VER} version of this example, "
|
||||
f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html"
|
||||
)
|
||||
from telegram import KeyboardButton, ReplyKeyboardMarkup, ReplyKeyboardRemove, Update, WebAppInfo
|
||||
from telegram.ext import Application, CommandHandler, ContextTypes, MessageHandler, filters
|
||||
|
||||
@@ -58,8 +45,10 @@ async def web_app_data(update: Update, context: ContextTypes.DEFAULT_TYPE) -> No
|
||||
# (see webappbot.html)
|
||||
data = json.loads(update.effective_message.web_app_data.data)
|
||||
await update.message.reply_html(
|
||||
text=f"You selected the color with the HEX value <code>{data['hex']}</code>. The "
|
||||
f"corresponding RGB value is <code>{tuple(data['rgb'].values())}</code>.",
|
||||
text=(
|
||||
f"You selected the color with the HEX value <code>{data['hex']}</code>. The "
|
||||
f"corresponding RGB value is <code>{tuple(data['rgb'].values())}</code>."
|
||||
),
|
||||
reply_markup=ReplyKeyboardRemove(),
|
||||
)
|
||||
|
||||
|
||||
+2
-3
@@ -12,10 +12,9 @@ target-version = "py38"
|
||||
show-fixes = true
|
||||
ignore = ["PLR2004", "PLR0911", "PLR0912", "PLR0913", "PLR0915", "PERF203"]
|
||||
select = ["E", "F", "I", "PL", "UP", "RUF", "PTH", "C4", "B", "PIE", "SIM", "RET", "RSE",
|
||||
"G", "ISC", "PT", "ASYNC", "TCH", "CPY", "SLOT", "PERF",]
|
||||
"G", "ISC", "PT", "ASYNC", "TCH", "SLOT", "PERF", "PYI", "FLY", "AIR"]
|
||||
# Add "FURB" after it's out of preview
|
||||
|
||||
[tool.ruff.per-file-ignores]
|
||||
"tests/*.py" = ["B018"]
|
||||
"**/__init__.py" = ["CPY001"]
|
||||
"examples/**.py" = ["CPY001"]
|
||||
"tests/**.py" = ["RUF012"]
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
pre-commit # needed for pre-commit hooks in the git commit command
|
||||
|
||||
# For the test suite
|
||||
pytest==7.4.0
|
||||
pytest-asyncio==0.21.0 # needed because pytest doesn't come with native support for coroutines as tests
|
||||
pytest==7.4.2
|
||||
pytest-asyncio==0.21.1 # needed because pytest doesn't come with native support for coroutines as tests
|
||||
pytest-xdist==3.3.1 # xdist runs tests in parallel
|
||||
flaky # Used for flaky tests (flaky decorator)
|
||||
beautifulsoup4 # used in test_official for parsing tg docs
|
||||
|
||||
@@ -16,12 +16,12 @@ cryptography!=3.4,!=3.4.1,!=3.4.2,!=3.4.3,>=39.0.1 # passport
|
||||
aiolimiter~=1.1.0 # rate-limiter!ext
|
||||
|
||||
# tornado is rather stable, but let's not allow the next mayor release without prior testing
|
||||
tornado~=6.2 # webhooks!ext
|
||||
tornado~=6.3.3 # webhooks!ext
|
||||
|
||||
# Cachetools and APS don't have a strict stability policy.
|
||||
# Let's be cautious for now.
|
||||
cachetools~=5.3.1 # callback-data!ext
|
||||
APScheduler~=3.10.1 # job-queue!ext
|
||||
APScheduler~=3.10.4 # job-queue!ext
|
||||
|
||||
# pytz is required by APS and just needs the lower bound due to #2120
|
||||
pytz>=2018.6 # job-queue!ext
|
||||
|
||||
+1
-1
@@ -6,4 +6,4 @@
|
||||
# versions and only increase the lower bound if necessary
|
||||
|
||||
# httpx has no stable release yet, so let's be cautious for now
|
||||
httpx ~= 0.24.1
|
||||
httpx ~= 0.25.0
|
||||
|
||||
@@ -19,7 +19,7 @@ exclude = setup.py, setup-raw.py docs/source/conf.py
|
||||
disable = duplicate-code,too-many-arguments,too-many-public-methods,too-few-public-methods,
|
||||
broad-except,too-many-instance-attributes,fixme,missing-function-docstring,
|
||||
missing-class-docstring,too-many-locals,too-many-lines,too-many-branches,
|
||||
too-many-statements
|
||||
too-many-statements, cyclic-import
|
||||
enable=useless-suppression ; Warns about unused pylint ignores
|
||||
exclude-protected=_unfrozen
|
||||
|
||||
@@ -78,9 +78,17 @@ warn_unused_ignores = False
|
||||
[mypy-apscheduler.*]
|
||||
ignore_missing_imports = True
|
||||
|
||||
# uvicorn and starlette are only used for the `customwebhookbot.py` example
|
||||
# The libs listed below are only used for the `customwebhookbot_*.py` examples
|
||||
# let's just ignore type checking for them for now
|
||||
[mypy-uvicorn.*]
|
||||
ignore_missing_imports = True
|
||||
[mypy-starlette.*]
|
||||
ignore_missing_imports = True
|
||||
[mypy-asgiref.*]
|
||||
ignore_missing_imports = True
|
||||
[mypy-flask.*]
|
||||
ignore_missing_imports = True
|
||||
[mypy-quart.*]
|
||||
ignore_missing_imports = True
|
||||
[mypy-django.*]
|
||||
ignore_missing_imports = True
|
||||
|
||||
@@ -109,6 +109,7 @@ def get_setup_kwargs(raw=False):
|
||||
"Programming Language :: Python :: 3.9",
|
||||
"Programming Language :: Python :: 3.10",
|
||||
"Programming Language :: Python :: 3.11",
|
||||
"Programming Language :: Python :: 3.12",
|
||||
],
|
||||
python_requires=">=3.8",
|
||||
)
|
||||
|
||||
@@ -170,6 +170,7 @@ __all__ = ( # Keep this alphabetically ordered
|
||||
"ShippingQuery",
|
||||
"Sticker",
|
||||
"StickerSet",
|
||||
"Story",
|
||||
"SuccessfulPayment",
|
||||
"SwitchInlineQueryChosenChat",
|
||||
"TelegramObject",
|
||||
@@ -341,6 +342,7 @@ from ._replykeyboardmarkup import ReplyKeyboardMarkup
|
||||
from ._replykeyboardremove import ReplyKeyboardRemove
|
||||
from ._sentwebappmessage import SentWebAppMessage
|
||||
from ._shared import ChatShared, UserShared
|
||||
from ._story import Story
|
||||
from ._switchinlinequerychosenchat import SwitchInlineQueryChosenChat
|
||||
from ._telegramobject import TelegramObject
|
||||
from ._update import Update
|
||||
|
||||
+397
-816
File diff suppressed because it is too large
Load Diff
@@ -100,7 +100,7 @@ class BotCommandScope(TelegramObject):
|
||||
if not data:
|
||||
return None
|
||||
|
||||
_class_mapping: Dict[str, Type["BotCommandScope"]] = {
|
||||
_class_mapping: Dict[str, Type[BotCommandScope]] = {
|
||||
cls.DEFAULT: BotCommandScopeDefault,
|
||||
cls.ALL_PRIVATE_CHATS: BotCommandScopeAllPrivateChats,
|
||||
cls.ALL_GROUP_CHATS: BotCommandScopeAllGroupChats,
|
||||
|
||||
@@ -127,7 +127,7 @@ class CallbackQuery(TelegramObject):
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
# Required
|
||||
self.id: str = id # pylint: disable=invalid-name
|
||||
self.id: str = id
|
||||
self.from_user: User = from_user
|
||||
self.chat_instance: str = chat_instance
|
||||
# Optionals
|
||||
@@ -531,7 +531,7 @@ class CallbackQuery(TelegramObject):
|
||||
|
||||
async def set_game_score(
|
||||
self,
|
||||
user_id: Union[int, str],
|
||||
user_id: int,
|
||||
score: int,
|
||||
force: Optional[bool] = None,
|
||||
disable_edit_message: Optional[bool] = None,
|
||||
@@ -589,7 +589,7 @@ class CallbackQuery(TelegramObject):
|
||||
|
||||
async def get_game_high_scores(
|
||||
self,
|
||||
user_id: Union[int, str],
|
||||
user_id: int,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
|
||||
+69
-16
@@ -31,6 +31,7 @@ from telegram._menubutton import MenuButton
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._utils import enum
|
||||
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||
from telegram._utils.datetime import extract_tzinfo_from_defaults, from_timestamp
|
||||
from telegram._utils.defaultvalue import DEFAULT_NONE
|
||||
from telegram._utils.types import (
|
||||
CorrectOptionID,
|
||||
@@ -172,6 +173,12 @@ class Chat(TelegramObject):
|
||||
:meth:`telegram.Bot.get_chat`.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
emoji_status_expiration_date (:class:`datetime.datetime`, optional): Expiration date of
|
||||
emoji status of the other party in a private chat, in seconds. Returned only in
|
||||
:meth:`telegram.Bot.get_chat`.
|
||||
|datetime_localization|
|
||||
|
||||
.. versionadded:: 20.5
|
||||
has_aggressive_anti_spam_enabled (:obj:`bool`, optional): :obj:`True`, if aggressive
|
||||
anti-spam checks are enabled in the supergroup. The field is only available to chat
|
||||
administrators. Returned only in :meth:`telegram.Bot.get_chat`.
|
||||
@@ -265,6 +272,12 @@ class Chat(TelegramObject):
|
||||
:meth:`telegram.Bot.get_chat`.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
emoji_status_expiration_date (:class:`datetime.datetime`, optional): Expiration date of
|
||||
emoji status of the other party in a private chat, in seconds. Returned only in
|
||||
:meth:`telegram.Bot.get_chat`.
|
||||
|datetime_localization|
|
||||
|
||||
.. versionadded:: 20.5
|
||||
has_aggressive_anti_spam_enabled (:obj:`bool`): Optional. :obj:`True`, if aggressive
|
||||
anti-spam checks are enabled in the supergroup. The field is only available to chat
|
||||
administrators. Returned only in :meth:`telegram.Bot.get_chat`.
|
||||
@@ -306,6 +319,7 @@ class Chat(TelegramObject):
|
||||
"is_forum",
|
||||
"active_usernames",
|
||||
"emoji_status_custom_emoji_id",
|
||||
"emoji_status_expiration_date",
|
||||
"has_hidden_members",
|
||||
"has_aggressive_anti_spam_enabled",
|
||||
)
|
||||
@@ -352,6 +366,7 @@ class Chat(TelegramObject):
|
||||
is_forum: Optional[bool] = None,
|
||||
active_usernames: Optional[Sequence[str]] = None,
|
||||
emoji_status_custom_emoji_id: Optional[str] = None,
|
||||
emoji_status_expiration_date: Optional[datetime] = None,
|
||||
has_aggressive_anti_spam_enabled: Optional[bool] = None,
|
||||
has_hidden_members: Optional[bool] = None,
|
||||
*,
|
||||
@@ -359,7 +374,7 @@ class Chat(TelegramObject):
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
# Required
|
||||
self.id: int = id # pylint: disable=invalid-name
|
||||
self.id: int = id
|
||||
self.type: str = enum.get_member(constants.ChatType, type, type)
|
||||
# Optionals
|
||||
self.title: Optional[str] = title
|
||||
@@ -390,6 +405,7 @@ class Chat(TelegramObject):
|
||||
self.is_forum: Optional[bool] = is_forum
|
||||
self.active_usernames: Tuple[str, ...] = parse_sequence_arg(active_usernames)
|
||||
self.emoji_status_custom_emoji_id: Optional[str] = emoji_status_custom_emoji_id
|
||||
self.emoji_status_expiration_date: Optional[datetime] = emoji_status_expiration_date
|
||||
self.has_aggressive_anti_spam_enabled: Optional[bool] = has_aggressive_anti_spam_enabled
|
||||
self.has_hidden_members: Optional[bool] = has_hidden_members
|
||||
|
||||
@@ -446,6 +462,13 @@ class Chat(TelegramObject):
|
||||
if not data:
|
||||
return None
|
||||
|
||||
# Get the local timezone from the bot if it has defaults
|
||||
loc_tzinfo = extract_tzinfo_from_defaults(bot)
|
||||
|
||||
data["emoji_status_expiration_date"] = from_timestamp(
|
||||
data.get("emoji_status_expiration_date"), tzinfo=loc_tzinfo
|
||||
)
|
||||
|
||||
data["photo"] = ChatPhoto.de_json(data.get("photo"), bot)
|
||||
from telegram import Message # pylint: disable=import-outside-toplevel
|
||||
|
||||
@@ -654,7 +677,7 @@ class Chat(TelegramObject):
|
||||
|
||||
async def get_member(
|
||||
self,
|
||||
user_id: Union[str, int],
|
||||
user_id: int,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
@@ -684,7 +707,7 @@ class Chat(TelegramObject):
|
||||
|
||||
async def ban_member(
|
||||
self,
|
||||
user_id: Union[str, int],
|
||||
user_id: int,
|
||||
revoke_messages: Optional[bool] = None,
|
||||
until_date: Optional[Union[int, datetime]] = None,
|
||||
*,
|
||||
@@ -854,7 +877,7 @@ class Chat(TelegramObject):
|
||||
|
||||
async def unban_member(
|
||||
self,
|
||||
user_id: Union[str, int],
|
||||
user_id: int,
|
||||
only_if_banned: Optional[bool] = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
@@ -886,7 +909,7 @@ class Chat(TelegramObject):
|
||||
|
||||
async def promote_member(
|
||||
self,
|
||||
user_id: Union[str, int],
|
||||
user_id: int,
|
||||
can_change_info: Optional[bool] = None,
|
||||
can_post_messages: Optional[bool] = None,
|
||||
can_edit_messages: Optional[bool] = None,
|
||||
@@ -899,6 +922,9 @@ class Chat(TelegramObject):
|
||||
can_manage_chat: Optional[bool] = None,
|
||||
can_manage_video_chats: Optional[bool] = None,
|
||||
can_manage_topics: Optional[bool] = None,
|
||||
can_post_stories: Optional[bool] = None,
|
||||
can_edit_stories: Optional[bool] = None,
|
||||
can_delete_stories: Optional[bool] = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
@@ -918,6 +944,9 @@ class Chat(TelegramObject):
|
||||
The argument ``can_manage_voice_chats`` was renamed to
|
||||
:paramref:`~telegram.Bot.promote_chat_member.can_manage_video_chats` in accordance to
|
||||
Bot API 6.0.
|
||||
.. versionchanged:: 20.6
|
||||
The arguments `can_post_stories`, `can_edit_stories` and `can_delete_stories` were
|
||||
added.
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
@@ -943,11 +972,14 @@ class Chat(TelegramObject):
|
||||
can_manage_chat=can_manage_chat,
|
||||
can_manage_video_chats=can_manage_video_chats,
|
||||
can_manage_topics=can_manage_topics,
|
||||
can_post_stories=can_post_stories,
|
||||
can_edit_stories=can_edit_stories,
|
||||
can_delete_stories=can_delete_stories,
|
||||
)
|
||||
|
||||
async def restrict_member(
|
||||
self,
|
||||
user_id: Union[str, int],
|
||||
user_id: int,
|
||||
permissions: ChatPermissions,
|
||||
until_date: Optional[Union[int, datetime]] = None,
|
||||
use_independent_chat_permissions: Optional[bool] = None,
|
||||
@@ -1534,7 +1566,6 @@ class Chat(TelegramObject):
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
reply_markup: Optional[ReplyMarkup] = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
thumb: Optional[FileInput] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
caption_entities: Optional[Sequence["MessageEntity"]] = None,
|
||||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -1569,7 +1600,6 @@ class Chat(TelegramObject):
|
||||
reply_to_message_id=reply_to_message_id,
|
||||
reply_markup=reply_markup,
|
||||
parse_mode=parse_mode,
|
||||
thumb=thumb,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
caption_entities=caption_entities,
|
||||
filename=filename,
|
||||
@@ -1591,7 +1621,6 @@ class Chat(TelegramObject):
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
reply_markup: Optional[ReplyMarkup] = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
thumb: Optional[FileInput] = None,
|
||||
disable_content_type_detection: Optional[bool] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
caption_entities: Optional[Sequence["MessageEntity"]] = None,
|
||||
@@ -1629,7 +1658,6 @@ class Chat(TelegramObject):
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
parse_mode=parse_mode,
|
||||
thumb=thumb,
|
||||
thumbnail=thumbnail,
|
||||
api_kwargs=api_kwargs,
|
||||
disable_content_type_detection=disable_content_type_detection,
|
||||
@@ -1875,7 +1903,6 @@ class Chat(TelegramObject):
|
||||
duration: Optional[int] = None,
|
||||
width: Optional[int] = None,
|
||||
height: Optional[int] = None,
|
||||
thumb: Optional[FileInput] = None,
|
||||
caption: Optional[str] = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
disable_notification: DVInput[bool] = DEFAULT_NONE,
|
||||
@@ -1911,7 +1938,6 @@ class Chat(TelegramObject):
|
||||
duration=duration,
|
||||
width=width,
|
||||
height=height,
|
||||
thumb=thumb,
|
||||
caption=caption,
|
||||
parse_mode=parse_mode,
|
||||
disable_notification=disable_notification,
|
||||
@@ -2045,7 +2071,6 @@ class Chat(TelegramObject):
|
||||
height: Optional[int] = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
supports_streaming: Optional[bool] = None,
|
||||
thumb: Optional[FileInput] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
caption_entities: Optional[Sequence["MessageEntity"]] = None,
|
||||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -2086,7 +2111,6 @@ class Chat(TelegramObject):
|
||||
height=height,
|
||||
parse_mode=parse_mode,
|
||||
supports_streaming=supports_streaming,
|
||||
thumb=thumb,
|
||||
thumbnail=thumbnail,
|
||||
api_kwargs=api_kwargs,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
@@ -2105,7 +2129,6 @@ class Chat(TelegramObject):
|
||||
disable_notification: DVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
reply_markup: Optional[ReplyMarkup] = None,
|
||||
thumb: Optional[FileInput] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
message_thread_id: Optional[int] = None,
|
||||
@@ -2140,7 +2163,6 @@ class Chat(TelegramObject):
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
thumb=thumb,
|
||||
thumbnail=thumbnail,
|
||||
api_kwargs=api_kwargs,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
@@ -2904,6 +2926,37 @@ class Chat(TelegramObject):
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
async def unpin_all_general_forum_topic_messages(
|
||||
self,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
pool_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
) -> bool:
|
||||
"""Shortcut for::
|
||||
|
||||
await bot.unpin_all_general_forum_topic_messages(chat_id=update.effective_chat.id,
|
||||
*args, **kwargs)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.unpin_all_general_forum_topic_messages`.
|
||||
|
||||
.. versionadded:: 20.5
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
"""
|
||||
return await self.get_bot().unpin_all_general_forum_topic_messages(
|
||||
chat_id=self.id,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
async def edit_general_forum_topic(
|
||||
self,
|
||||
name: str,
|
||||
|
||||
@@ -31,26 +31,31 @@ class ChatAdministratorRights(TelegramObject):
|
||||
:attr:`can_delete_messages`, :attr:`can_manage_video_chats`, :attr:`can_restrict_members`,
|
||||
:attr:`can_promote_members`, :attr:`can_change_info`, :attr:`can_invite_users`,
|
||||
:attr:`can_post_messages`, :attr:`can_edit_messages`, :attr:`can_pin_messages`,
|
||||
:attr:`can_manage_topics` are equal.
|
||||
:attr:`can_manage_topics`, :attr:`can_post_stories`, :attr:`can_delete_stories`, and
|
||||
:attr:`can_edit_stories` are equal.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
:attr:`can_manage_topics` is considered as well when comparing objects of
|
||||
this type in terms of equality.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
.. versionchanged:: 20.6
|
||||
:attr:`can_post_stories`, :attr:`can_edit_stories`, and :attr:`can_delete_stories` are
|
||||
considered as well when comparing objects of this type in terms of equality.
|
||||
|
||||
Args:
|
||||
is_anonymous (:obj:`bool`): :obj:`True`, if the user's presence in the chat is hidden.
|
||||
can_manage_chat (:obj:`bool`): :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.
|
||||
log, chat statistics, boost list in channels, see channel members, report spam
|
||||
messages, see anonymous administrators in supergroups and ignore slow mode.
|
||||
Implied by any other administrator privilege.
|
||||
can_delete_messages (:obj:`bool`): :obj:`True`, if the administrator can delete messages of
|
||||
other users.
|
||||
can_manage_video_chats (:obj:`bool`): :obj:`True`, if the administrator can manage video
|
||||
chats.
|
||||
can_restrict_members (:obj:`bool`): :obj:`True`, if the administrator can restrict, ban or
|
||||
unban chat members.
|
||||
unban chat members, or access supergroup statistics.
|
||||
can_promote_members (:obj:`bool`): :obj:`True`, if the administrator can add new
|
||||
administrators with a subset of their own privileges or demote administrators
|
||||
that they have promoted, directly or indirectly (promoted by administrators that
|
||||
@@ -60,11 +65,23 @@ class ChatAdministratorRights(TelegramObject):
|
||||
can_invite_users (:obj:`bool`): :obj:`True`, if the user is allowed to invite new users to
|
||||
the chat.
|
||||
can_post_messages (:obj:`bool`, optional): :obj:`True`, if the administrator can post
|
||||
messages in the channel; channels only.
|
||||
messages in the channel, or access channel statistics; channels only.
|
||||
can_edit_messages (:obj:`bool`, optional): :obj:`True`, if the administrator can edit
|
||||
messages of other users.
|
||||
can_pin_messages (:obj:`bool`, optional): :obj:`True`, if the user is allowed to pin
|
||||
messages; groups and supergroups only.
|
||||
can_post_stories (:obj:`bool`, optional): :obj:`True`, if the administrator can post
|
||||
stories in the channel; channels only.
|
||||
|
||||
.. versionadded:: 20.6
|
||||
can_edit_stories (:obj:`bool`, optional): :obj:`True`, if the administrator can edit
|
||||
stories posted by other users; channels only.
|
||||
|
||||
.. versionadded:: 20.6
|
||||
can_delete_stories (:obj:`bool`, optional): :obj:`True`, if the administrator can delete
|
||||
stories posted by other users; channels only.
|
||||
|
||||
.. versionadded:: 20.6
|
||||
can_manage_topics (:obj:`bool`, optional): :obj:`True`, if the user is allowed
|
||||
to create, rename, close, and reopen forum topics; supergroups only.
|
||||
|
||||
@@ -73,15 +90,15 @@ class ChatAdministratorRights(TelegramObject):
|
||||
Attributes:
|
||||
is_anonymous (:obj:`bool`): :obj:`True`, if the user's presence in the chat is hidden.
|
||||
can_manage_chat (:obj:`bool`): :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.
|
||||
log, chat statistics, boost list in channels, see channel members, report spam
|
||||
messages, see anonymous administrators in supergroups and ignore slow mode.
|
||||
Implied by any other administrator privilege.
|
||||
can_delete_messages (:obj:`bool`): :obj:`True`, if the administrator can delete messages of
|
||||
other users.
|
||||
can_manage_video_chats (:obj:`bool`): :obj:`True`, if the administrator can manage video
|
||||
chats.
|
||||
can_restrict_members (:obj:`bool`): :obj:`True`, if the administrator can restrict, ban or
|
||||
unban chat members.
|
||||
unban chat members, or access supergroup statistics.
|
||||
can_promote_members (:obj:`bool`): :obj:`True`, if the administrator can add new
|
||||
administrators with a subset of their own privileges or demote administrators that he
|
||||
has promoted, directly or indirectly (promoted by administrators that were appointed by
|
||||
@@ -91,11 +108,23 @@ class ChatAdministratorRights(TelegramObject):
|
||||
can_invite_users (:obj:`bool`): :obj:`True`, if the user is allowed to invite new users to
|
||||
the chat.
|
||||
can_post_messages (:obj:`bool`): Optional. :obj:`True`, if the administrator can post
|
||||
messages in the channel; channels only.
|
||||
messages in the channel, or access channel statistics; channels only.
|
||||
can_edit_messages (:obj:`bool`): Optional. :obj:`True`, if the administrator can edit
|
||||
messages of other users.
|
||||
can_pin_messages (:obj:`bool`): Optional. :obj:`True`, if the user is allowed to pin
|
||||
messages; groups and supergroups only.
|
||||
can_post_stories (:obj:`bool`): Optional. :obj:`True`, if the administrator can post
|
||||
stories in the channel; channels only.
|
||||
|
||||
.. versionadded:: 20.6
|
||||
can_edit_stories (:obj:`bool`): Optional. :obj:`True`, if the administrator can edit
|
||||
stories posted by other users; channels only.
|
||||
|
||||
.. versionadded:: 20.6
|
||||
can_delete_stories (:obj:`bool`): Optional. :obj:`True`, if the administrator can delete
|
||||
stories posted by other users; channels only.
|
||||
|
||||
.. versionadded:: 20.6
|
||||
can_manage_topics (:obj:`bool`): Optional. :obj:`True`, if the user is allowed
|
||||
to create, rename, close, and reopen forum topics; supergroups only.
|
||||
|
||||
@@ -115,6 +144,9 @@ class ChatAdministratorRights(TelegramObject):
|
||||
"can_edit_messages",
|
||||
"can_pin_messages",
|
||||
"can_manage_topics",
|
||||
"can_post_stories",
|
||||
"can_edit_stories",
|
||||
"can_delete_stories",
|
||||
)
|
||||
|
||||
def __init__(
|
||||
@@ -131,6 +163,9 @@ class ChatAdministratorRights(TelegramObject):
|
||||
can_edit_messages: Optional[bool] = None,
|
||||
can_pin_messages: Optional[bool] = None,
|
||||
can_manage_topics: Optional[bool] = None,
|
||||
can_post_stories: Optional[bool] = None,
|
||||
can_edit_stories: Optional[bool] = None,
|
||||
can_delete_stories: Optional[bool] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
) -> None:
|
||||
@@ -148,6 +183,9 @@ class ChatAdministratorRights(TelegramObject):
|
||||
self.can_post_messages: Optional[bool] = can_post_messages
|
||||
self.can_edit_messages: Optional[bool] = can_edit_messages
|
||||
self.can_pin_messages: Optional[bool] = can_pin_messages
|
||||
self.can_post_stories: Optional[bool] = can_post_stories
|
||||
self.can_edit_stories: Optional[bool] = can_edit_stories
|
||||
self.can_delete_stories: Optional[bool] = can_delete_stories
|
||||
self.can_manage_topics: Optional[bool] = can_manage_topics
|
||||
|
||||
self._id_attrs = (
|
||||
@@ -163,6 +201,9 @@ class ChatAdministratorRights(TelegramObject):
|
||||
self.can_edit_messages,
|
||||
self.can_pin_messages,
|
||||
self.can_manage_topics,
|
||||
self.can_post_stories,
|
||||
self.can_edit_stories,
|
||||
self.can_delete_stories,
|
||||
)
|
||||
|
||||
self._freeze()
|
||||
@@ -176,7 +217,7 @@ class ChatAdministratorRights(TelegramObject):
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
return cls(True, True, True, True, True, True, True, True, True, True, True, True)
|
||||
return cls(*(True,) * len(cls.__slots__))
|
||||
|
||||
@classmethod
|
||||
def no_rights(cls) -> "ChatAdministratorRights":
|
||||
@@ -186,6 +227,4 @@ class ChatAdministratorRights(TelegramObject):
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
return cls(
|
||||
False, False, False, False, False, False, False, False, False, False, False, False
|
||||
)
|
||||
return cls(*(False,) * len(cls.__slots__))
|
||||
|
||||
@@ -63,7 +63,7 @@ class ChatJoinRequest(TelegramObject):
|
||||
request. This number may have more than 32 significant bits and some programming
|
||||
languages may have difficulty/silent defects in interpreting it. But it has at most 52
|
||||
significant bits, so a 64-bit integer or double-precision float type are safe for
|
||||
storing this identifier. The bot can use this identifier for 24 hours to send messages
|
||||
storing this identifier. The bot can use this identifier for 5 minutes to send messages
|
||||
until the join request is processed, assuming no other administrator contacted the
|
||||
user.
|
||||
|
||||
|
||||
+52
-21
@@ -111,7 +111,7 @@ class ChatMember(TelegramObject):
|
||||
if not data:
|
||||
return None
|
||||
|
||||
_class_mapping: Dict[str, Type["ChatMember"]] = {
|
||||
_class_mapping: Dict[str, Type[ChatMember]] = {
|
||||
cls.OWNER: ChatMemberOwner,
|
||||
cls.ADMINISTRATOR: ChatMemberAdministrator,
|
||||
cls.MEMBER: ChatMemberMember,
|
||||
@@ -130,6 +130,12 @@ class ChatMember(TelegramObject):
|
||||
|
||||
data["until_date"] = from_timestamp(data["until_date"], tzinfo=loc_tzinfo)
|
||||
|
||||
# This is a deprecated field that TG still returns for backwards compatibility
|
||||
# Let's filter it out to speed up the de-json process
|
||||
if cls is ChatMemberRestricted and data.get("can_send_media_messages") is not None:
|
||||
api_kwargs = {"can_send_media_messages": data.pop("can_send_media_messages")}
|
||||
return super()._de_json(data=data, bot=bot, api_kwargs=api_kwargs)
|
||||
|
||||
return super().de_json(data=data, bot=bot)
|
||||
|
||||
|
||||
@@ -212,12 +218,25 @@ class ChatMemberAdministrator(ChatMember):
|
||||
can_invite_users (:obj:`bool`): :obj:`True`, if the user can invite
|
||||
new users to the chat.
|
||||
can_post_messages (:obj:`bool`, optional): :obj:`True`, if the
|
||||
administrator can post in the channel, channels only.
|
||||
administrator can post messages in the channel, or access channel statistics; channels
|
||||
only.
|
||||
can_edit_messages (:obj:`bool`, optional): :obj:`True`, if the
|
||||
administrator can edit messages of other users and can pin
|
||||
messages; channels only.
|
||||
can_pin_messages (:obj:`bool`, optional): :obj:`True`, if the user is allowed
|
||||
to pin messages; groups and supergroups only.
|
||||
can_post_stories (:obj:`bool`, optional): :obj:`True`, if the administrator can post
|
||||
stories in the channel; channels only.
|
||||
|
||||
.. versionadded:: 20.6
|
||||
can_edit_stories (:obj:`bool`, optional): :obj:`True`, if the administrator can edit
|
||||
stories posted by other users; channels only.
|
||||
|
||||
.. versionadded:: 20.6
|
||||
can_delete_stories (:obj:`bool`, optional): :obj:`True`, if the administrator can delete
|
||||
stories posted by other users; channels only.
|
||||
|
||||
.. versionadded:: 20.6
|
||||
can_manage_topics (:obj:`bool`, optional): :obj:`True`, if the user is allowed
|
||||
to create, rename, close, and reopen forum topics; supergroups only.
|
||||
|
||||
@@ -232,10 +251,10 @@ class ChatMemberAdministrator(ChatMember):
|
||||
is allowed to edit administrator privileges of that user.
|
||||
is_anonymous (:obj:`bool`): :obj:`True`, if the user's
|
||||
presence in the chat is hidden.
|
||||
can_manage_chat (:obj:`bool`): :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.
|
||||
can_manage_chat (:obj:`bool`): :obj:`True`, if the administrator can access the chat event
|
||||
log, chat statistics, boost list in channels, see channel members, report spam
|
||||
messages, see anonymous administrators in supergroups and ignore slow mode.
|
||||
Implied by any other administrator privilege.
|
||||
can_delete_messages (:obj:`bool`): :obj:`True`, if the
|
||||
administrator can delete messages of other users.
|
||||
can_manage_video_chats (:obj:`bool`): :obj:`True`, if the
|
||||
@@ -243,7 +262,7 @@ class ChatMemberAdministrator(ChatMember):
|
||||
|
||||
.. versionadded:: 20.0
|
||||
can_restrict_members (:obj:`bool`): :obj:`True`, if the
|
||||
administrator can restrict, ban or unban chat members.
|
||||
administrator can restrict, ban or unban chat members, or access supergroup statistics.
|
||||
can_promote_members (:obj:`bool`): :obj:`True`, if the administrator can add new
|
||||
administrators with a subset of their own privileges or demote administrators
|
||||
that they have promoted, directly or indirectly (promoted by administrators that
|
||||
@@ -253,12 +272,25 @@ class ChatMemberAdministrator(ChatMember):
|
||||
can_invite_users (:obj:`bool`): :obj:`True`, if the user can invite
|
||||
new users to the chat.
|
||||
can_post_messages (:obj:`bool`): Optional. :obj:`True`, if the
|
||||
administrator can post in the channel, channels only.
|
||||
administrator can post messages in the channel or access channel statistics;
|
||||
channels only.
|
||||
can_edit_messages (:obj:`bool`): Optional. :obj:`True`, if the
|
||||
administrator can edit messages of other users and can pin
|
||||
messages; channels only.
|
||||
can_pin_messages (:obj:`bool`): Optional. :obj:`True`, if the user is allowed
|
||||
to pin messages; groups and supergroups only.
|
||||
can_post_stories (:obj:`bool`): Optional. :obj:`True`, if the administrator can post
|
||||
stories in the channel; channels only.
|
||||
|
||||
.. versionadded:: 20.6
|
||||
can_edit_stories (:obj:`bool`): Optional. :obj:`True`, if the administrator can edit
|
||||
stories posted by other users; channels only.
|
||||
|
||||
.. versionadded:: 20.6
|
||||
can_delete_stories (:obj:`bool`): Optional. :obj:`True`, if the administrator can delete
|
||||
stories posted by other users; channels only.
|
||||
|
||||
.. versionadded:: 20.6
|
||||
can_manage_topics (:obj:`bool`): Optional. :obj:`True`, if the user is allowed
|
||||
to create, rename, close, and reopen forum topics; supergroups only
|
||||
|
||||
@@ -281,6 +313,9 @@ class ChatMemberAdministrator(ChatMember):
|
||||
"can_pin_messages",
|
||||
"can_manage_topics",
|
||||
"custom_title",
|
||||
"can_post_stories",
|
||||
"can_edit_stories",
|
||||
"can_delete_stories",
|
||||
)
|
||||
|
||||
def __init__(
|
||||
@@ -300,6 +335,9 @@ class ChatMemberAdministrator(ChatMember):
|
||||
can_pin_messages: Optional[bool] = None,
|
||||
can_manage_topics: Optional[bool] = None,
|
||||
custom_title: Optional[str] = None,
|
||||
can_post_stories: Optional[bool] = None,
|
||||
can_edit_stories: Optional[bool] = None,
|
||||
can_delete_stories: Optional[bool] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
@@ -319,6 +357,9 @@ class ChatMemberAdministrator(ChatMember):
|
||||
self.can_pin_messages: Optional[bool] = can_pin_messages
|
||||
self.can_manage_topics: Optional[bool] = can_manage_topics
|
||||
self.custom_title: Optional[str] = custom_title
|
||||
self.can_post_stories: Optional[bool] = can_post_stories
|
||||
self.can_edit_stories: Optional[bool] = can_edit_stories
|
||||
self.can_delete_stories: Optional[bool] = can_delete_stories
|
||||
|
||||
|
||||
class ChatMemberMember(ChatMember):
|
||||
@@ -360,6 +401,9 @@ class ChatMemberRestricted(ChatMember):
|
||||
All arguments were made positional and their order was changed.
|
||||
The argument can_manage_topics was added.
|
||||
|
||||
.. versionchanged:: 20.5
|
||||
Removed deprecated argument and attribute ``can_send_media_messages``.
|
||||
|
||||
Args:
|
||||
user (:class:`telegram.User`): Information about the user.
|
||||
is_member (:obj:`bool`): :obj:`True`, if the user is a
|
||||
@@ -372,11 +416,6 @@ class ChatMemberRestricted(ChatMember):
|
||||
to pin messages; groups and supergroups only.
|
||||
can_send_messages (:obj:`bool`): :obj:`True`, if the user is allowed
|
||||
to send text messages, contacts, invoices, locations and venues.
|
||||
can_send_media_messages (:obj:`bool`): :obj:`True`, if the user is allowed
|
||||
to send audios, documents, photos, videos, video notes and voice notes.
|
||||
|
||||
.. deprecated:: 20.1
|
||||
Bot API 6.5 replaced this argument with granular media settings.
|
||||
can_send_polls (:obj:`bool`): :obj:`True`, if the user is allowed
|
||||
to send polls.
|
||||
can_send_other_messages (:obj:`bool`): :obj:`True`, if the user is allowed
|
||||
@@ -427,11 +466,6 @@ class ChatMemberRestricted(ChatMember):
|
||||
to pin messages; groups and supergroups only.
|
||||
can_send_messages (:obj:`bool`): :obj:`True`, if the user is allowed
|
||||
to send text messages, contacts, locations and venues.
|
||||
can_send_media_messages (:obj:`bool`): :obj:`True`, if the user is allowed
|
||||
to send audios, documents, photos, videos, video notes and voice notes.
|
||||
|
||||
.. deprecated:: 20.1
|
||||
Bot API 6.5 replaced this attribute with granular media settings.
|
||||
can_send_polls (:obj:`bool`): :obj:`True`, if the user is allowed
|
||||
to send polls.
|
||||
can_send_other_messages (:obj:`bool`): :obj:`True`, if the user is allowed
|
||||
@@ -476,7 +510,6 @@ class ChatMemberRestricted(ChatMember):
|
||||
"can_invite_users",
|
||||
"can_pin_messages",
|
||||
"can_send_messages",
|
||||
"can_send_media_messages",
|
||||
"can_send_polls",
|
||||
"can_send_other_messages",
|
||||
"can_add_web_page_previews",
|
||||
@@ -498,7 +531,6 @@ class ChatMemberRestricted(ChatMember):
|
||||
can_invite_users: bool,
|
||||
can_pin_messages: bool,
|
||||
can_send_messages: bool,
|
||||
can_send_media_messages: bool,
|
||||
can_send_polls: bool,
|
||||
can_send_other_messages: bool,
|
||||
can_add_web_page_previews: bool,
|
||||
@@ -520,7 +552,6 @@ class ChatMemberRestricted(ChatMember):
|
||||
self.can_invite_users: bool = can_invite_users
|
||||
self.can_pin_messages: bool = can_pin_messages
|
||||
self.can_send_messages: bool = can_send_messages
|
||||
self.can_send_media_messages: bool = can_send_media_messages
|
||||
self.can_send_polls: bool = can_send_polls
|
||||
self.can_send_other_messages: bool = can_send_other_messages
|
||||
self.can_add_web_page_previews: bool = can_add_web_page_previews
|
||||
|
||||
@@ -17,31 +17,36 @@
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram ChatPermission."""
|
||||
from typing import Optional
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._utils.types import JSONDict
|
||||
from telegram._utils.warnings import warn
|
||||
from telegram.warnings import PTBDeprecationWarning
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import Bot
|
||||
|
||||
|
||||
class ChatPermissions(TelegramObject):
|
||||
"""Describes actions that a non-administrator user is allowed to take in a chat.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`can_send_messages`, :attr:`can_send_media_messages`,
|
||||
considered equal, if their :attr:`can_send_messages`,
|
||||
:attr:`can_send_polls`, :attr:`can_send_other_messages`, :attr:`can_add_web_page_previews`,
|
||||
:attr:`can_change_info`, :attr:`can_invite_users`, :attr:`can_pin_messages`, and
|
||||
:attr:`can_change_info`, :attr:`can_invite_users`, :attr:`can_pin_messages`,
|
||||
:attr:`can_send_audios`, :attr:`can_send_documents`, :attr:`can_send_photos`,
|
||||
:attr:`can_send_videos`, :attr:`can_send_video_notes`, :attr:`can_send_voice_notes`, and
|
||||
:attr:`can_manage_topics` are equal.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
:attr:`can_manage_topics` is considered as well when comparing objects of
|
||||
this type in terms of equality.
|
||||
.. deprecated:: 20.1
|
||||
:attr:`can_send_audios`, :attr:`can_send_documents`, :attr:`can_send_photos`,
|
||||
:attr:`can_send_videos`, :attr:`can_send_video_notes` and :attr:`can_send_voice_notes`
|
||||
will be considered as well when comparing objects of this type in terms of equality in
|
||||
V21.
|
||||
.. versionchanged:: 20.5
|
||||
|
||||
* :attr:`can_send_audios`, :attr:`can_send_documents`, :attr:`can_send_photos`,
|
||||
:attr:`can_send_videos`, :attr:`can_send_video_notes` and :attr:`can_send_voice_notes`
|
||||
are considered as well when comparing objects of this type in terms of equality.
|
||||
* Removed deprecated argument and attribute ``can_send_media_messages``.
|
||||
|
||||
|
||||
Note:
|
||||
Though not stated explicitly in the official docs, Telegram changes not only the
|
||||
@@ -51,19 +56,11 @@ class ChatPermissions(TelegramObject):
|
||||
Args:
|
||||
can_send_messages (:obj:`bool`, optional): :obj:`True`, if the user is allowed to send text
|
||||
messages, contacts, locations and venues.
|
||||
can_send_media_messages (:obj:`bool`, optional): :obj:`True`, if the user is allowed to
|
||||
send audios, documents, photos, videos, video notes and voice notes, implies
|
||||
:attr:`can_send_messages`.
|
||||
|
||||
.. deprecated:: 20.1
|
||||
Bot API 6.5 replaced this argument with granular media settings.
|
||||
can_send_polls (:obj:`bool`, optional): :obj:`True`, if the user is allowed to send polls,
|
||||
implies :attr:`can_send_messages`.
|
||||
can_send_polls (:obj:`bool`, optional): :obj:`True`, if the user is allowed to send polls.
|
||||
can_send_other_messages (:obj:`bool`, optional): :obj:`True`, if the user is allowed to
|
||||
send animations, games, stickers and use inline bots, implies
|
||||
:attr:`can_send_media_messages`.
|
||||
send animations, games, stickers and use inline bots.
|
||||
can_add_web_page_previews (:obj:`bool`, optional): :obj:`True`, if the user is allowed to
|
||||
add web page previews to their messages, implies :attr:`can_send_media_messages`.
|
||||
add web page previews to their messages.
|
||||
can_change_info (:obj:`bool`, optional): :obj:`True`, if the user is allowed to change the
|
||||
chat title, photo and other settings. Ignored in public supergroups.
|
||||
can_invite_users (:obj:`bool`, optional): :obj:`True`, if the user is allowed to invite new
|
||||
@@ -99,19 +96,12 @@ class ChatPermissions(TelegramObject):
|
||||
Attributes:
|
||||
can_send_messages (:obj:`bool`): Optional. :obj:`True`, if the user is allowed to send text
|
||||
messages, contacts, locations and venues.
|
||||
can_send_media_messages (:obj:`bool`): Optional. :obj:`True`, if the user is allowed to
|
||||
send audios, documents, photos, videos, video notes and voice notes, implies
|
||||
:attr:`can_send_messages`.
|
||||
|
||||
.. deprecated:: 20.1
|
||||
Bot API 6.5 replaced this attribute with granular media settings.
|
||||
can_send_polls (:obj:`bool`): Optional. :obj:`True`, if the user is allowed to send polls,
|
||||
implies :attr:`can_send_messages`.
|
||||
can_send_other_messages (:obj:`bool`): Optional. :obj:`True`, if the user is allowed to
|
||||
send animations, games, stickers and use inline bots, implies
|
||||
:attr:`can_send_media_messages`.
|
||||
send animations, games, stickers and use inline bots.
|
||||
can_add_web_page_previews (:obj:`bool`): Optional. :obj:`True`, if the user is allowed to
|
||||
add web page previews to their messages, implies :attr:`can_send_media_messages`.
|
||||
add web page previews to their messages.
|
||||
can_change_info (:obj:`bool`): Optional. :obj:`True`, if the user is allowed to change the
|
||||
chat title, photo and other settings. Ignored in public supergroups.
|
||||
can_invite_users (:obj:`bool`): Optional. :obj:`True`, if the user is allowed to invite
|
||||
@@ -151,7 +141,6 @@ class ChatPermissions(TelegramObject):
|
||||
"can_invite_users",
|
||||
"can_send_polls",
|
||||
"can_send_messages",
|
||||
"can_send_media_messages",
|
||||
"can_change_info",
|
||||
"can_pin_messages",
|
||||
"can_add_web_page_previews",
|
||||
@@ -167,7 +156,6 @@ class ChatPermissions(TelegramObject):
|
||||
def __init__(
|
||||
self,
|
||||
can_send_messages: Optional[bool] = None,
|
||||
can_send_media_messages: Optional[bool] = None,
|
||||
can_send_polls: Optional[bool] = None,
|
||||
can_send_other_messages: Optional[bool] = None,
|
||||
can_add_web_page_previews: Optional[bool] = None,
|
||||
@@ -187,7 +175,6 @@ class ChatPermissions(TelegramObject):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
# Required
|
||||
self.can_send_messages: Optional[bool] = can_send_messages
|
||||
self.can_send_media_messages: Optional[bool] = can_send_media_messages
|
||||
self.can_send_polls: Optional[bool] = can_send_polls
|
||||
self.can_send_other_messages: Optional[bool] = can_send_other_messages
|
||||
self.can_add_web_page_previews: Optional[bool] = can_add_web_page_previews
|
||||
@@ -204,7 +191,6 @@ class ChatPermissions(TelegramObject):
|
||||
|
||||
self._id_attrs = (
|
||||
self.can_send_messages,
|
||||
self.can_send_media_messages,
|
||||
self.can_send_polls,
|
||||
self.can_send_other_messages,
|
||||
self.can_add_web_page_previews,
|
||||
@@ -212,23 +198,16 @@ class ChatPermissions(TelegramObject):
|
||||
self.can_invite_users,
|
||||
self.can_pin_messages,
|
||||
self.can_manage_topics,
|
||||
self.can_send_audios,
|
||||
self.can_send_documents,
|
||||
self.can_send_photos,
|
||||
self.can_send_videos,
|
||||
self.can_send_video_notes,
|
||||
self.can_send_voice_notes,
|
||||
)
|
||||
|
||||
self._freeze()
|
||||
|
||||
def __eq__(self, other: object) -> bool:
|
||||
warn(
|
||||
"In v21, granular media settings will be considered as well when comparing"
|
||||
" ChatPermissions instances.",
|
||||
PTBDeprecationWarning,
|
||||
stacklevel=2,
|
||||
)
|
||||
return super().__eq__(other)
|
||||
|
||||
def __hash__(self) -> int:
|
||||
# Intend: Added so support the own __eq__ function (which otherwise breaks hashing)
|
||||
return super().__hash__()
|
||||
|
||||
@classmethod
|
||||
def all_permissions(cls) -> "ChatPermissions":
|
||||
"""
|
||||
@@ -239,7 +218,7 @@ class ChatPermissions(TelegramObject):
|
||||
.. versionadded:: 20.0
|
||||
|
||||
"""
|
||||
return cls(*(15 * (True,)))
|
||||
return cls(*(14 * (True,)))
|
||||
|
||||
@classmethod
|
||||
def no_permissions(cls) -> "ChatPermissions":
|
||||
@@ -249,4 +228,20 @@ class ChatPermissions(TelegramObject):
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
return cls(*(15 * (False,)))
|
||||
return cls(*(14 * (False,)))
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["ChatPermissions"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
if not data:
|
||||
return None
|
||||
|
||||
api_kwargs = {}
|
||||
# This is a deprecated field that TG still returns for backwards compatibility
|
||||
# Let's filter it out to speed up the de-json process
|
||||
if data.get("can_send_media_messages") is not None:
|
||||
api_kwargs["can_send_media_messages"] = data.pop("can_send_media_messages")
|
||||
|
||||
return super()._de_json(data=data, bot=bot, api_kwargs=api_kwargs)
|
||||
|
||||
@@ -22,10 +22,6 @@ from typing import TYPE_CHECKING, Optional, Type, TypeVar
|
||||
from telegram._files._basemedium import _BaseMedium
|
||||
from telegram._files.photosize import PhotoSize
|
||||
from telegram._utils.types import JSONDict
|
||||
from telegram._utils.warnings_transition import (
|
||||
warn_about_deprecated_arg_return_new_arg,
|
||||
warn_about_deprecated_attr_in_property,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import Bot
|
||||
@@ -48,10 +44,6 @@ class _BaseThumbedMedium(_BaseMedium):
|
||||
is supposed to be the same over time and for different bots.
|
||||
Can't be used to download or reuse the file.
|
||||
file_size (:obj:`int`, optional): File size.
|
||||
thumb (:class:`telegram.PhotoSize`, optional): Thumbnail as defined by sender.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbargumentdeprecation| :paramref:`thumbnail`.
|
||||
thumbnail (:class:`telegram.PhotoSize`, optional): Thumbnail as defined by sender.
|
||||
|
||||
.. versionadded:: 20.2
|
||||
@@ -75,7 +67,6 @@ class _BaseThumbedMedium(_BaseMedium):
|
||||
file_id: str,
|
||||
file_unique_id: str,
|
||||
file_size: Optional[int] = None,
|
||||
thumb: Optional[PhotoSize] = None,
|
||||
thumbnail: Optional[PhotoSize] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
@@ -87,26 +78,7 @@ class _BaseThumbedMedium(_BaseMedium):
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
self.thumbnail: Optional[PhotoSize] = warn_about_deprecated_arg_return_new_arg(
|
||||
deprecated_arg=thumb,
|
||||
new_arg=thumbnail,
|
||||
deprecated_arg_name="thumb",
|
||||
new_arg_name="thumbnail",
|
||||
bot_api_version="6.6",
|
||||
stacklevel=3,
|
||||
)
|
||||
|
||||
@property
|
||||
def thumb(self) -> Optional[PhotoSize]:
|
||||
""":class:`telegram.PhotoSize`: Optional. Thumbnail as defined by sender.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbattributedeprecation| :attr:`thumbnail`.
|
||||
"""
|
||||
warn_about_deprecated_attr_in_property(
|
||||
deprecated_attr_name="thumb", new_attr_name="thumbnail", bot_api_version="6.6"
|
||||
)
|
||||
return self.thumbnail
|
||||
self.thumbnail: Optional[PhotoSize] = thumbnail
|
||||
|
||||
@classmethod
|
||||
def de_json(
|
||||
|
||||
@@ -30,6 +30,9 @@ class Animation(_BaseThumbedMedium):
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`file_unique_id` is equal.
|
||||
|
||||
.. versionchanged:: 20.5
|
||||
|removed_thumb_note|
|
||||
|
||||
Args:
|
||||
file_id (:obj:`str`): Identifier for this file, which can be used to download
|
||||
or reuse the file.
|
||||
@@ -39,10 +42,6 @@ class Animation(_BaseThumbedMedium):
|
||||
width (:obj:`int`): Video width as defined by sender.
|
||||
height (:obj:`int`): Video height as defined by sender.
|
||||
duration (:obj:`int`): Duration of the video in seconds as defined by sender.
|
||||
thumb (:class:`telegram.PhotoSize`, optional): Animation thumbnail as defined by sender.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbargumentdeprecation| :paramref:`thumbnail`.
|
||||
file_name (:obj:`str`, optional): Original animation filename as defined by sender.
|
||||
mime_type (:obj:`str`, optional): MIME type of the file as defined by sender.
|
||||
file_size (:obj:`int`, optional): File size in bytes.
|
||||
@@ -79,7 +78,6 @@ class Animation(_BaseThumbedMedium):
|
||||
width: int,
|
||||
height: int,
|
||||
duration: int,
|
||||
thumb: Optional[PhotoSize] = None,
|
||||
file_name: Optional[str] = None,
|
||||
mime_type: Optional[str] = None,
|
||||
file_size: Optional[int] = None,
|
||||
@@ -91,7 +89,6 @@ class Animation(_BaseThumbedMedium):
|
||||
file_id=file_id,
|
||||
file_unique_id=file_unique_id,
|
||||
file_size=file_size,
|
||||
thumb=thumb,
|
||||
api_kwargs=api_kwargs,
|
||||
thumbnail=thumbnail,
|
||||
)
|
||||
|
||||
@@ -30,6 +30,9 @@ class Audio(_BaseThumbedMedium):
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`file_unique_id` is equal.
|
||||
|
||||
.. versionchanged:: 20.5
|
||||
|removed_thumb_note|
|
||||
|
||||
|
||||
Args:
|
||||
file_id (:obj:`str`): Identifier for this file, which can be used to download
|
||||
@@ -43,11 +46,6 @@ class Audio(_BaseThumbedMedium):
|
||||
file_name (:obj:`str`, optional): Original filename as defined by sender.
|
||||
mime_type (:obj:`str`, optional): MIME type of the file as defined by sender.
|
||||
file_size (:obj:`int`, optional): File size in bytes.
|
||||
thumb (:class:`telegram.PhotoSize`, optional): Thumbnail of the album cover to
|
||||
which the music file belongs.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbargumentdeprecation| :paramref:`thumbnail`.
|
||||
thumbnail (:class:`telegram.PhotoSize`, optional): Thumbnail of the album cover to
|
||||
which the music file belongs.
|
||||
|
||||
@@ -84,7 +82,6 @@ class Audio(_BaseThumbedMedium):
|
||||
title: Optional[str] = None,
|
||||
mime_type: Optional[str] = None,
|
||||
file_size: Optional[int] = None,
|
||||
thumb: Optional[PhotoSize] = None,
|
||||
file_name: Optional[str] = None,
|
||||
thumbnail: Optional[PhotoSize] = None,
|
||||
*,
|
||||
@@ -94,7 +91,6 @@ class Audio(_BaseThumbedMedium):
|
||||
file_id=file_id,
|
||||
file_unique_id=file_unique_id,
|
||||
file_size=file_size,
|
||||
thumb=thumb,
|
||||
thumbnail=thumbnail,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
@@ -31,15 +31,14 @@ class Document(_BaseThumbedMedium):
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`file_unique_id` is equal.
|
||||
|
||||
.. versionchanged:: 20.5
|
||||
|removed_thumb_note|
|
||||
|
||||
Args:
|
||||
file_id (:obj:`str`): Identifier for this file, which can be used to download
|
||||
or reuse the file.
|
||||
file_unique_id (:obj:`str`): Unique identifier for this file, which is supposed to be
|
||||
the same over time and for different bots. Can't be used to download or reuse the file.
|
||||
thumb (:class:`telegram.PhotoSize`, optional): Document thumbnail as defined by sender.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbargumentdeprecation| :paramref:`thumbnail`.
|
||||
file_name (:obj:`str`, optional): Original filename as defined by sender.
|
||||
mime_type (:obj:`str`, optional): MIME type of the file as defined by sender.
|
||||
file_size (:obj:`int`, optional): File size in bytes.
|
||||
@@ -67,7 +66,6 @@ class Document(_BaseThumbedMedium):
|
||||
self,
|
||||
file_id: str,
|
||||
file_unique_id: str,
|
||||
thumb: Optional[PhotoSize] = None,
|
||||
file_name: Optional[str] = None,
|
||||
mime_type: Optional[str] = None,
|
||||
file_size: Optional[int] = None,
|
||||
@@ -79,7 +77,6 @@ class Document(_BaseThumbedMedium):
|
||||
file_id=file_id,
|
||||
file_unique_id=file_unique_id,
|
||||
file_size=file_size,
|
||||
thumb=thumb,
|
||||
thumbnail=thumbnail,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
@@ -99,7 +99,7 @@ class File(TelegramObject):
|
||||
self.file_size: Optional[int] = file_size
|
||||
self.file_path: Optional[str] = file_path
|
||||
|
||||
self._credentials: Optional["FileCredentials"] = None
|
||||
self._credentials: Optional[FileCredentials] = None
|
||||
|
||||
self._id_attrs = (self.file_unique_id,)
|
||||
|
||||
|
||||
+31
-109
@@ -31,10 +31,6 @@ from telegram._utils.argumentparsing import parse_sequence_arg
|
||||
from telegram._utils.defaultvalue import DEFAULT_NONE
|
||||
from telegram._utils.files import parse_file_input
|
||||
from telegram._utils.types import FileInput, JSONDict, ODVInput
|
||||
from telegram._utils.warnings_transition import (
|
||||
warn_about_deprecated_attr_in_property,
|
||||
warn_about_thumb_return_thumbnail,
|
||||
)
|
||||
from telegram.constants import InputMediaType
|
||||
|
||||
MediaType = Union[Animation, Audio, Document, PhotoSize, Video]
|
||||
@@ -107,11 +103,13 @@ class InputMedia(TelegramObject):
|
||||
self._freeze()
|
||||
|
||||
@staticmethod
|
||||
def _parse_thumb_input(thumb: Optional[FileInput]) -> Optional[Union[str, InputFile]]:
|
||||
def _parse_thumbnail_input(thumbnail: Optional[FileInput]) -> Optional[Union[str, InputFile]]:
|
||||
# We use local_mode=True because we don't have access to the actual setting and want
|
||||
# things to work in local mode.
|
||||
return (
|
||||
parse_file_input(thumb, attach=True, local_mode=True) if thumb is not None else thumb
|
||||
parse_file_input(thumbnail, attach=True, local_mode=True)
|
||||
if thumbnail is not None
|
||||
else thumbnail
|
||||
)
|
||||
|
||||
|
||||
@@ -125,6 +123,9 @@ class InputMediaAnimation(InputMedia):
|
||||
|
||||
.. seealso:: :wiki:`Working with Files and Media <Working-with-Files-and-Media>`
|
||||
|
||||
.. versionchanged:: 20.5
|
||||
|removed_thumb_note|
|
||||
|
||||
Args:
|
||||
media (:obj:`str` | :term:`file object` | :obj:`bytes` | :class:`pathlib.Path` | \
|
||||
:class:`telegram.Animation`): File to send. |fileinputnopath|
|
||||
@@ -137,14 +138,6 @@ class InputMediaAnimation(InputMedia):
|
||||
:obj:`tempfile` module.
|
||||
|
||||
.. versionadded:: 13.1
|
||||
thumb (:term:`file object` | :obj:`bytes` | :class:`pathlib.Path` | :obj:`str`, \
|
||||
optional): |thumbdocstringnopath|
|
||||
|
||||
.. versionchanged:: 13.2
|
||||
Accept :obj:`bytes` as input.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbargumentdeprecation| :paramref:`thumbnail`.
|
||||
caption (:obj:`str`, optional): Caption of the animation to be sent,
|
||||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters
|
||||
after entities parsing.
|
||||
@@ -196,7 +189,6 @@ class InputMediaAnimation(InputMedia):
|
||||
def __init__(
|
||||
self,
|
||||
media: Union[FileInput, Animation],
|
||||
thumb: Optional[FileInput] = None,
|
||||
caption: Optional[str] = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
width: Optional[int] = None,
|
||||
@@ -219,7 +211,6 @@ class InputMediaAnimation(InputMedia):
|
||||
# things to work in local mode.
|
||||
media = parse_file_input(media, filename=filename, attach=True, local_mode=True)
|
||||
|
||||
thumbnail = warn_about_thumb_return_thumbnail(deprecated_arg=thumb, new_arg=thumbnail)
|
||||
super().__init__(
|
||||
InputMediaType.ANIMATION,
|
||||
media,
|
||||
@@ -229,26 +220,14 @@ class InputMediaAnimation(InputMedia):
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
with self._unfrozen():
|
||||
self.thumbnail: Optional[Union[str, InputFile]] = self._parse_thumb_input(thumbnail)
|
||||
self.thumbnail: Optional[Union[str, InputFile]] = self._parse_thumbnail_input(
|
||||
thumbnail
|
||||
)
|
||||
self.width: Optional[int] = width
|
||||
self.height: Optional[int] = height
|
||||
self.duration: Optional[int] = duration
|
||||
self.has_spoiler: Optional[bool] = has_spoiler
|
||||
|
||||
@property
|
||||
def thumb(self) -> Optional[Union[str, InputFile]]:
|
||||
""":class:`telegram.InputFile`: Optional. |thumbdocstringbase|
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbattributedeprecation| :attr:`thumbnail`.
|
||||
"""
|
||||
warn_about_deprecated_attr_in_property(
|
||||
deprecated_attr_name="thumb",
|
||||
new_attr_name="thumbnail",
|
||||
bot_api_version="6.6",
|
||||
)
|
||||
return self.thumbnail
|
||||
|
||||
|
||||
class InputMediaPhoto(InputMedia):
|
||||
"""Represents a photo to be sent.
|
||||
@@ -337,9 +316,12 @@ class InputMediaVideo(InputMedia):
|
||||
* When using a :class:`telegram.Video` for the :attr:`media` attribute, it will take the
|
||||
width, height and duration from that video, unless otherwise specified with the optional
|
||||
arguments.
|
||||
* :paramref:`thumb` will be ignored for small video files, for which Telegram can easily
|
||||
generate thumbnails. However, this behaviour is undocumented and might be changed
|
||||
by Telegram.
|
||||
* :paramref:`thumbnail` will be ignored for small video files, for which Telegram can
|
||||
easily generate thumbnails. However, this behaviour is undocumented and might be
|
||||
changed by Telegram.
|
||||
|
||||
.. versionchanged:: 20.5
|
||||
|removed_thumb_note|
|
||||
|
||||
Args:
|
||||
media (:obj:`str` | :term:`file object` | :obj:`bytes` | :class:`pathlib.Path` | \
|
||||
@@ -367,14 +349,6 @@ class InputMediaVideo(InputMedia):
|
||||
duration (:obj:`int`, optional): Video duration in seconds.
|
||||
supports_streaming (:obj:`bool`, optional): Pass :obj:`True`, if the uploaded video is
|
||||
suitable for streaming.
|
||||
thumb (:term:`file object` | :obj:`bytes` | :class:`pathlib.Path` | :obj:`str`, \
|
||||
optional): |thumbdocstringnopath|
|
||||
|
||||
.. versionchanged:: 13.2
|
||||
Accept :obj:`bytes` as input.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbargumentdeprecation| :paramref:`thumbnail`.
|
||||
has_spoiler (:obj:`bool`, optional): Pass :obj:`True`, if the video needs to be covered
|
||||
with a spoiler animation.
|
||||
|
||||
@@ -429,7 +403,6 @@ class InputMediaVideo(InputMedia):
|
||||
duration: Optional[int] = None,
|
||||
supports_streaming: Optional[bool] = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
thumb: Optional[FileInput] = None,
|
||||
caption_entities: Optional[Sequence[MessageEntity]] = None,
|
||||
filename: Optional[str] = None,
|
||||
has_spoiler: Optional[bool] = None,
|
||||
@@ -447,7 +420,6 @@ class InputMediaVideo(InputMedia):
|
||||
# things to work in local mode.
|
||||
media = parse_file_input(media, filename=filename, attach=True, local_mode=True)
|
||||
|
||||
thumbnail = warn_about_thumb_return_thumbnail(deprecated_arg=thumb, new_arg=thumbnail)
|
||||
super().__init__(
|
||||
InputMediaType.VIDEO,
|
||||
media,
|
||||
@@ -460,24 +432,12 @@ class InputMediaVideo(InputMedia):
|
||||
self.width: Optional[int] = width
|
||||
self.height: Optional[int] = height
|
||||
self.duration: Optional[int] = duration
|
||||
self.thumbnail: Optional[Union[str, InputFile]] = self._parse_thumb_input(thumbnail)
|
||||
self.thumbnail: Optional[Union[str, InputFile]] = self._parse_thumbnail_input(
|
||||
thumbnail
|
||||
)
|
||||
self.supports_streaming: Optional[bool] = supports_streaming
|
||||
self.has_spoiler: Optional[bool] = has_spoiler
|
||||
|
||||
@property
|
||||
def thumb(self) -> Optional[Union[str, InputFile]]:
|
||||
""":class:`telegram.InputFile`: Optional. |thumbdocstringbase|
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbattributedeprecation| :attr:`thumbnail`.
|
||||
"""
|
||||
warn_about_deprecated_attr_in_property(
|
||||
deprecated_attr_name="thumb",
|
||||
new_attr_name="thumbnail",
|
||||
bot_api_version="6.6",
|
||||
)
|
||||
return self.thumbnail
|
||||
|
||||
|
||||
class InputMediaAudio(InputMedia):
|
||||
"""Represents an audio file to be treated as music to be sent.
|
||||
@@ -489,6 +449,9 @@ class InputMediaAudio(InputMedia):
|
||||
duration, performer and title from that video, unless otherwise specified with the
|
||||
optional arguments.
|
||||
|
||||
.. versionchanged:: 20.5
|
||||
|removed_thumb_note|
|
||||
|
||||
Args:
|
||||
media (:obj:`str` | :term:`file object` | :obj:`bytes` | :class:`pathlib.Path` | \
|
||||
:class:`telegram.Audio`): File to send. |fileinputnopath|
|
||||
@@ -514,14 +477,6 @@ class InputMediaAudio(InputMedia):
|
||||
performer (:obj:`str`, optional): Performer of the audio as defined by sender or by audio
|
||||
tags.
|
||||
title (:obj:`str`, optional): Title of the audio as defined by sender or by audio tags.
|
||||
thumb (:term:`file object` | :obj:`bytes` | :class:`pathlib.Path` | :obj:`str`, \
|
||||
optional): |thumbdocstringnopath|
|
||||
|
||||
.. versionchanged:: 13.2
|
||||
Accept :obj:`bytes` as input.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbargumentdeprecation| :paramref:`thumbnail`.
|
||||
thumbnail (:term:`file object` | :obj:`bytes` | :class:`pathlib.Path` | :obj:`str`, \
|
||||
optional): |thumbdocstringnopath|
|
||||
|
||||
@@ -555,7 +510,6 @@ class InputMediaAudio(InputMedia):
|
||||
def __init__(
|
||||
self,
|
||||
media: Union[FileInput, Audio],
|
||||
thumb: Optional[FileInput] = None,
|
||||
caption: Optional[str] = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
duration: Optional[int] = None,
|
||||
@@ -577,7 +531,6 @@ class InputMediaAudio(InputMedia):
|
||||
# things to work in local mode.
|
||||
media = parse_file_input(media, filename=filename, attach=True, local_mode=True)
|
||||
|
||||
thumbnail = warn_about_thumb_return_thumbnail(deprecated_arg=thumb, new_arg=thumbnail)
|
||||
super().__init__(
|
||||
InputMediaType.AUDIO,
|
||||
media,
|
||||
@@ -587,31 +540,22 @@ class InputMediaAudio(InputMedia):
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
with self._unfrozen():
|
||||
self.thumbnail: Optional[Union[str, InputFile]] = self._parse_thumb_input(thumbnail)
|
||||
self.thumbnail: Optional[Union[str, InputFile]] = self._parse_thumbnail_input(
|
||||
thumbnail
|
||||
)
|
||||
self.duration: Optional[int] = duration
|
||||
self.title: Optional[str] = title
|
||||
self.performer: Optional[str] = performer
|
||||
|
||||
@property
|
||||
def thumb(self) -> Optional[Union[str, InputFile]]:
|
||||
""":class:`telegram.InputFile`: Optional. |thumbdocstringbase|
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbattributedeprecation| :attr:`thumbnail`.
|
||||
"""
|
||||
warn_about_deprecated_attr_in_property(
|
||||
deprecated_attr_name="thumb",
|
||||
new_attr_name="thumbnail",
|
||||
bot_api_version="6.6",
|
||||
)
|
||||
return self.thumbnail
|
||||
|
||||
|
||||
class InputMediaDocument(InputMedia):
|
||||
"""Represents a general file to be sent.
|
||||
|
||||
.. seealso:: :wiki:`Working with Files and Media <Working-with-Files-and-Media>`
|
||||
|
||||
.. versionchanged:: 20.5
|
||||
|removed_thumb_note|
|
||||
|
||||
Args:
|
||||
media (:obj:`str` | :term:`file object` | :obj:`bytes` | :class:`pathlib.Path` | \
|
||||
:class:`telegram.Document`): File to send. |fileinputnopath|
|
||||
@@ -633,14 +577,6 @@ class InputMediaDocument(InputMedia):
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceclassargs|
|
||||
|
||||
thumb (:term:`file object` | :obj:`bytes` | :class:`pathlib.Path` | :obj:`str`, \
|
||||
optional): |thumbdocstringnopath|
|
||||
|
||||
.. versionchanged:: 13.2
|
||||
Accept :obj:`bytes` as input.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbargumentdeprecation| :paramref:`thumbnail`.
|
||||
disable_content_type_detection (:obj:`bool`, optional): Disables automatic server-side
|
||||
content type detection for files uploaded using multipart/form-data. Always
|
||||
:obj:`True`, if the document is sent as part of an album.
|
||||
@@ -675,7 +611,6 @@ class InputMediaDocument(InputMedia):
|
||||
def __init__(
|
||||
self,
|
||||
media: Union[FileInput, Document],
|
||||
thumb: Optional[FileInput] = None,
|
||||
caption: Optional[str] = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
disable_content_type_detection: Optional[bool] = None,
|
||||
@@ -689,7 +624,6 @@ class InputMediaDocument(InputMedia):
|
||||
# things to work in local mode.
|
||||
media = parse_file_input(media, Document, filename=filename, attach=True, local_mode=True)
|
||||
|
||||
thumbnail = warn_about_thumb_return_thumbnail(deprecated_arg=thumb, new_arg=thumbnail)
|
||||
super().__init__(
|
||||
InputMediaType.DOCUMENT,
|
||||
media,
|
||||
@@ -699,19 +633,7 @@ class InputMediaDocument(InputMedia):
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
with self._unfrozen():
|
||||
self.thumbnail: Optional[Union[str, InputFile]] = self._parse_thumb_input(thumbnail)
|
||||
self.thumbnail: Optional[Union[str, InputFile]] = self._parse_thumbnail_input(
|
||||
thumbnail
|
||||
)
|
||||
self.disable_content_type_detection: Optional[bool] = disable_content_type_detection
|
||||
|
||||
@property
|
||||
def thumb(self) -> Optional[Union[str, InputFile]]:
|
||||
""":class:`telegram.InputFile`: Optional. |thumbdocstringbase|
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbattributedeprecation| :attr:`thumbnail`.
|
||||
"""
|
||||
warn_about_deprecated_attr_in_property(
|
||||
deprecated_attr_name="thumb",
|
||||
new_attr_name="thumbnail",
|
||||
bot_api_version="6.6",
|
||||
)
|
||||
return self.thumbnail
|
||||
|
||||
@@ -26,10 +26,6 @@ from telegram._files.photosize import PhotoSize
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||
from telegram._utils.types import JSONDict
|
||||
from telegram._utils.warnings_transition import (
|
||||
warn_about_deprecated_attr_in_property,
|
||||
warn_about_thumb_return_thumbnail,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import Bot
|
||||
@@ -46,6 +42,9 @@ class Sticker(_BaseThumbedMedium):
|
||||
arguments had to be changed. Use keyword arguments to make sure that the arguments are
|
||||
passed correctly.
|
||||
|
||||
.. versionchanged:: 20.5
|
||||
|removed_thumb_note|
|
||||
|
||||
Args:
|
||||
file_id (:obj:`str`): Identifier for this file, which can be used to download
|
||||
or reuse the file.
|
||||
@@ -63,11 +62,6 @@ class Sticker(_BaseThumbedMedium):
|
||||
format, which is determined by the fields :attr:`is_animated` and :attr:`is_video`.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
thumb (:class:`telegram.PhotoSize`, optional): Sticker thumbnail in the ``.WEBP`` or
|
||||
``.JPG`` format.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbargumentdeprecation| :paramref:`thumbnail`.
|
||||
emoji (:obj:`str`, optional): Emoji associated with the sticker
|
||||
set_name (:obj:`str`, optional): Name of the sticker set to which the sticker belongs.
|
||||
mask_position (:class:`telegram.MaskPosition`, optional): For mask stickers, the position
|
||||
@@ -157,7 +151,6 @@ class Sticker(_BaseThumbedMedium):
|
||||
is_animated: bool,
|
||||
is_video: bool,
|
||||
type: str, # pylint: disable=redefined-builtin
|
||||
thumb: Optional[PhotoSize] = None,
|
||||
emoji: Optional[str] = None,
|
||||
file_size: Optional[int] = None,
|
||||
set_name: Optional[str] = None,
|
||||
@@ -173,7 +166,6 @@ class Sticker(_BaseThumbedMedium):
|
||||
file_id=file_id,
|
||||
file_unique_id=file_unique_id,
|
||||
file_size=file_size,
|
||||
thumb=thumb,
|
||||
thumbnail=thumbnail,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
@@ -234,6 +226,9 @@ class StickerSet(TelegramObject):
|
||||
.. versionchanged:: 20.0
|
||||
The parameter ``contains_masks`` has been removed. Use :paramref:`sticker_type` instead.
|
||||
|
||||
.. versionchanged:: 20.5
|
||||
|removed_thumb_note|
|
||||
|
||||
Args:
|
||||
name (:obj:`str`): Sticker set name.
|
||||
title (:obj:`str`): Sticker set title.
|
||||
@@ -251,11 +246,6 @@ class StickerSet(TelegramObject):
|
||||
:attr:`telegram.Sticker.CUSTOM_EMOJI`.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
thumb (:class:`telegram.PhotoSize`, optional): Sticker set thumbnail in the ``.WEBP``,
|
||||
``.TGS``, or ``.WEBM`` format.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbargumentdeprecation| :paramref:`thumbnail`.
|
||||
thumbnail (:class:`telegram.PhotoSize`, optional): Sticker set thumbnail in the ``.WEBP``,
|
||||
``.TGS``, or ``.WEBM`` format.
|
||||
|
||||
@@ -302,7 +292,6 @@ class StickerSet(TelegramObject):
|
||||
stickers: Sequence[Sticker],
|
||||
is_video: bool,
|
||||
sticker_type: str,
|
||||
thumb: Optional[PhotoSize] = None,
|
||||
thumbnail: Optional[PhotoSize] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
@@ -316,28 +305,11 @@ class StickerSet(TelegramObject):
|
||||
self.sticker_type: str = sticker_type
|
||||
# Optional
|
||||
|
||||
self.thumbnail: Optional[PhotoSize] = warn_about_thumb_return_thumbnail(
|
||||
deprecated_arg=thumb, new_arg=thumbnail
|
||||
)
|
||||
self.thumbnail: Optional[PhotoSize] = thumbnail
|
||||
self._id_attrs = (self.name,)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@property
|
||||
def thumb(self) -> Optional[PhotoSize]:
|
||||
""":class:`telegram.PhotoSize`: Optional. Sticker set thumbnail in the ``.WEBP``,
|
||||
``.TGS``, or ``.WEBM`` format.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbattributedeprecation| :attr:`thumbnail`.
|
||||
"""
|
||||
warn_about_deprecated_attr_in_property(
|
||||
deprecated_attr_name="thumb",
|
||||
new_attr_name="thumbnail",
|
||||
bot_api_version="6.6",
|
||||
)
|
||||
return self.thumbnail
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["StickerSet"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
|
||||
@@ -30,6 +30,9 @@ class Video(_BaseThumbedMedium):
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`file_unique_id` is equal.
|
||||
|
||||
.. versionchanged:: 20.5
|
||||
|removed_thumb_note|
|
||||
|
||||
Args:
|
||||
file_id (:obj:`str`): Identifier for this file, which can be used to download
|
||||
or reuse the file.
|
||||
@@ -39,10 +42,6 @@ class Video(_BaseThumbedMedium):
|
||||
width (:obj:`int`): Video width as defined by sender.
|
||||
height (:obj:`int`): Video height as defined by sender.
|
||||
duration (:obj:`int`): Duration of the video in seconds as defined by sender.
|
||||
thumb (:class:`telegram.PhotoSize`, optional): Video thumbnail.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbargumentdeprecation| :paramref:`thumbnail`.
|
||||
file_name (:obj:`str`, optional): Original filename as defined by sender.
|
||||
mime_type (:obj:`str`, optional): MIME type of a file as defined by sender.
|
||||
file_size (:obj:`int`, optional): File size in bytes.
|
||||
@@ -76,7 +75,6 @@ class Video(_BaseThumbedMedium):
|
||||
width: int,
|
||||
height: int,
|
||||
duration: int,
|
||||
thumb: Optional[PhotoSize] = None,
|
||||
mime_type: Optional[str] = None,
|
||||
file_size: Optional[int] = None,
|
||||
file_name: Optional[str] = None,
|
||||
@@ -88,7 +86,6 @@ class Video(_BaseThumbedMedium):
|
||||
file_id=file_id,
|
||||
file_unique_id=file_unique_id,
|
||||
file_size=file_size,
|
||||
thumb=thumb,
|
||||
thumbnail=thumbnail,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
@@ -31,6 +31,9 @@ class VideoNote(_BaseThumbedMedium):
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`file_unique_id` is equal.
|
||||
|
||||
.. versionchanged:: 20.5
|
||||
|removed_thumb_note|
|
||||
|
||||
Args:
|
||||
file_id (:obj:`str`): Identifier for this file, which can be used to download
|
||||
or reuse the file.
|
||||
@@ -40,10 +43,6 @@ class VideoNote(_BaseThumbedMedium):
|
||||
length (:obj:`int`): Video width and height (diameter of the video message) as defined
|
||||
by sender.
|
||||
duration (:obj:`int`): Duration of the video in seconds as defined by sender.
|
||||
thumb (:class:`telegram.PhotoSize`, optional): Video thumbnail.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbargumentdeprecation| :paramref:`thumbnail`.
|
||||
file_size (:obj:`int`, optional): File size in bytes.
|
||||
thumbnail (:class:`telegram.PhotoSize`, optional): Video thumbnail.
|
||||
|
||||
@@ -73,7 +72,6 @@ class VideoNote(_BaseThumbedMedium):
|
||||
file_unique_id: str,
|
||||
length: int,
|
||||
duration: int,
|
||||
thumb: Optional[PhotoSize] = None,
|
||||
file_size: Optional[int] = None,
|
||||
thumbnail: Optional[PhotoSize] = None,
|
||||
*,
|
||||
@@ -83,7 +81,6 @@ class VideoNote(_BaseThumbedMedium):
|
||||
file_id=file_id,
|
||||
file_unique_id=file_unique_id,
|
||||
file_size=file_size,
|
||||
thumb=thumb,
|
||||
thumbnail=thumbnail,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
@@ -111,7 +111,7 @@ class InlineQuery(TelegramObject):
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
# Required
|
||||
self.id: str = id # pylint: disable=invalid-name
|
||||
self.id: str = id
|
||||
self.from_user: User = from_user
|
||||
self.query: str = query
|
||||
self.offset: str = offset
|
||||
@@ -145,8 +145,6 @@ class InlineQuery(TelegramObject):
|
||||
cache_time: Optional[int] = None,
|
||||
is_personal: Optional[bool] = None,
|
||||
next_offset: Optional[str] = None,
|
||||
switch_pm_text: Optional[str] = None,
|
||||
switch_pm_parameter: Optional[str] = None,
|
||||
button: Optional[InlineQueryResultsButton] = None,
|
||||
*,
|
||||
current_offset: Optional[str] = None,
|
||||
@@ -192,8 +190,6 @@ class InlineQuery(TelegramObject):
|
||||
cache_time=cache_time,
|
||||
is_personal=is_personal,
|
||||
next_offset=next_offset,
|
||||
switch_pm_text=switch_pm_text,
|
||||
switch_pm_parameter=switch_pm_parameter,
|
||||
button=button,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
|
||||
@@ -60,7 +60,7 @@ class InlineQueryResult(TelegramObject):
|
||||
|
||||
# Required
|
||||
self.type: str = type
|
||||
self.id: str = str(id) # pylint: disable=invalid-name
|
||||
self.id: str = str(id)
|
||||
|
||||
self._id_attrs = (self.id,)
|
||||
|
||||
|
||||
@@ -23,10 +23,6 @@ from typing import TYPE_CHECKING, Optional
|
||||
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
|
||||
from telegram._inline.inlinequeryresult import InlineQueryResult
|
||||
from telegram._utils.types import JSONDict
|
||||
from telegram._utils.warnings_transition import (
|
||||
warn_about_deprecated_arg_return_new_arg,
|
||||
warn_about_deprecated_attr_in_property,
|
||||
)
|
||||
from telegram.constants import InlineQueryResultType
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@@ -39,6 +35,9 @@ class InlineQueryResultArticle(InlineQueryResult):
|
||||
Examples:
|
||||
:any:`Inline Bot <examples.inlinebot>`
|
||||
|
||||
.. versionchanged:: 20.5
|
||||
Removed the deprecated arguments and attributes ``thumb_*``.
|
||||
|
||||
Args:
|
||||
id (:obj:`str`): Unique identifier for this result,
|
||||
:tg-const:`telegram.InlineQueryResult.MIN_ID_LENGTH`-
|
||||
@@ -52,18 +51,6 @@ class InlineQueryResultArticle(InlineQueryResult):
|
||||
hide_url (:obj:`bool`, optional): Pass :obj:`True`, if you don't want the URL to be shown
|
||||
in the message.
|
||||
description (:obj:`str`, optional): Short description of the result.
|
||||
thumb_url (:obj:`str`, optional): Url of the thumbnail for the result.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbargumentdeprecation| :paramref:`thumbnail_url`.
|
||||
thumb_width (:obj:`int`, optional): Thumbnail width.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbargumentdeprecation| :paramref:`thumbnail_width`.
|
||||
thumb_height (:obj:`int`, optional): Thumbnail height.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbargumentdeprecation| :paramref:`thumbnail_height`.
|
||||
thumbnail_url (:obj:`str`, optional): Url of the thumbnail for the result.
|
||||
|
||||
.. versionadded:: 20.2
|
||||
@@ -121,9 +108,6 @@ class InlineQueryResultArticle(InlineQueryResult):
|
||||
url: Optional[str] = None,
|
||||
hide_url: Optional[bool] = None,
|
||||
description: Optional[str] = None,
|
||||
thumb_url: Optional[str] = None,
|
||||
thumb_width: Optional[int] = None,
|
||||
thumb_height: Optional[int] = None,
|
||||
thumbnail_url: Optional[str] = None,
|
||||
thumbnail_width: Optional[int] = None,
|
||||
thumbnail_height: Optional[int] = None,
|
||||
@@ -141,66 +125,6 @@ class InlineQueryResultArticle(InlineQueryResult):
|
||||
self.url: Optional[str] = url
|
||||
self.hide_url: Optional[bool] = hide_url
|
||||
self.description: Optional[str] = description
|
||||
self.thumbnail_url: Optional[str] = warn_about_deprecated_arg_return_new_arg(
|
||||
deprecated_arg=thumb_url,
|
||||
new_arg=thumbnail_url,
|
||||
deprecated_arg_name="thumb_url",
|
||||
new_arg_name="thumbnail_url",
|
||||
bot_api_version="6.6",
|
||||
)
|
||||
self.thumbnail_width: Optional[int] = warn_about_deprecated_arg_return_new_arg(
|
||||
deprecated_arg=thumb_width,
|
||||
new_arg=thumbnail_width,
|
||||
deprecated_arg_name="thumb_width",
|
||||
new_arg_name="thumbnail_width",
|
||||
bot_api_version="6.6",
|
||||
)
|
||||
self.thumbnail_height: Optional[int] = warn_about_deprecated_arg_return_new_arg(
|
||||
deprecated_arg=thumb_height,
|
||||
new_arg=thumbnail_height,
|
||||
deprecated_arg_name="thumb_height",
|
||||
new_arg_name="thumbnail_height",
|
||||
bot_api_version="6.6",
|
||||
)
|
||||
|
||||
@property
|
||||
def thumb_url(self) -> Optional[str]:
|
||||
""":obj:`str`: Optional. Url of the thumbnail for the result.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbattributedeprecation| :attr:`thumbnail_url`.
|
||||
"""
|
||||
warn_about_deprecated_attr_in_property(
|
||||
deprecated_attr_name="thumb_url",
|
||||
new_attr_name="thumbnail_url",
|
||||
bot_api_version="6.6",
|
||||
)
|
||||
return self.thumbnail_url
|
||||
|
||||
@property
|
||||
def thumb_width(self) -> Optional[int]:
|
||||
""":obj:`str`: Optional. Thumbnail width.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbattributedeprecation| :attr:`thumbnail_width`.
|
||||
"""
|
||||
warn_about_deprecated_attr_in_property(
|
||||
deprecated_attr_name="thumb_width",
|
||||
new_attr_name="thumbnail_width",
|
||||
bot_api_version="6.6",
|
||||
)
|
||||
return self.thumbnail_width
|
||||
|
||||
@property
|
||||
def thumb_height(self) -> Optional[int]:
|
||||
""":obj:`str`: Optional. Thumbnail height.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbattributedeprecation| :attr:`thumbnail_height`.
|
||||
"""
|
||||
warn_about_deprecated_attr_in_property(
|
||||
deprecated_attr_name="thumb_height",
|
||||
new_attr_name="thumbnail_height",
|
||||
bot_api_version="6.6",
|
||||
)
|
||||
return self.thumbnail_height
|
||||
self.thumbnail_url: Optional[str] = thumbnail_url
|
||||
self.thumbnail_width: Optional[int] = thumbnail_width
|
||||
self.thumbnail_height: Optional[int] = thumbnail_height
|
||||
|
||||
@@ -23,10 +23,6 @@ from typing import TYPE_CHECKING, Optional
|
||||
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
|
||||
from telegram._inline.inlinequeryresult import InlineQueryResult
|
||||
from telegram._utils.types import JSONDict
|
||||
from telegram._utils.warnings_transition import (
|
||||
warn_about_deprecated_arg_return_new_arg,
|
||||
warn_about_deprecated_attr_in_property,
|
||||
)
|
||||
from telegram.constants import InlineQueryResultType
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@@ -39,6 +35,9 @@ class InlineQueryResultContact(InlineQueryResult):
|
||||
Alternatively, you can use :attr:`input_message_content` to send a message with the specified
|
||||
content instead of the contact.
|
||||
|
||||
.. versionchanged:: 20.5
|
||||
|removed_thumb_wildcard_note|
|
||||
|
||||
Args:
|
||||
id (:obj:`str`): Unique identifier for this result,
|
||||
:tg-const:`telegram.InlineQueryResult.MIN_ID_LENGTH`-
|
||||
@@ -52,18 +51,6 @@ class InlineQueryResultContact(InlineQueryResult):
|
||||
to the message.
|
||||
input_message_content (:class:`telegram.InputMessageContent`, optional): Content of the
|
||||
message to be sent instead of the contact.
|
||||
thumb_url (:obj:`str`, optional): Url of the thumbnail for the result.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbargumentdeprecation| :paramref:`thumbnail_url`.
|
||||
thumb_width (:obj:`int`, optional): Thumbnail width.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbargumentdeprecation| :paramref:`thumbnail_width`.
|
||||
thumb_height (:obj:`int`, optional): Thumbnail height.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbargumentdeprecation| :paramref:`thumbnail_height`.
|
||||
thumbnail_url (:obj:`str`, optional): Url of the thumbnail for the result.
|
||||
|
||||
.. versionadded:: 20.2
|
||||
@@ -120,9 +107,6 @@ class InlineQueryResultContact(InlineQueryResult):
|
||||
last_name: Optional[str] = None,
|
||||
reply_markup: Optional[InlineKeyboardMarkup] = None,
|
||||
input_message_content: Optional["InputMessageContent"] = None,
|
||||
thumb_url: Optional[str] = None,
|
||||
thumb_width: Optional[int] = None,
|
||||
thumb_height: Optional[int] = None,
|
||||
vcard: Optional[str] = None,
|
||||
thumbnail_url: Optional[str] = None,
|
||||
thumbnail_width: Optional[int] = None,
|
||||
@@ -141,66 +125,6 @@ class InlineQueryResultContact(InlineQueryResult):
|
||||
self.vcard: Optional[str] = vcard
|
||||
self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup
|
||||
self.input_message_content: Optional[InputMessageContent] = input_message_content
|
||||
self.thumbnail_url: Optional[str] = warn_about_deprecated_arg_return_new_arg(
|
||||
deprecated_arg=thumb_url,
|
||||
new_arg=thumbnail_url,
|
||||
deprecated_arg_name="thumb_url",
|
||||
new_arg_name="thumbnail_url",
|
||||
bot_api_version="6.6",
|
||||
)
|
||||
self.thumbnail_width: Optional[int] = warn_about_deprecated_arg_return_new_arg(
|
||||
deprecated_arg=thumb_width,
|
||||
new_arg=thumbnail_width,
|
||||
deprecated_arg_name="thumb_width",
|
||||
new_arg_name="thumbnail_width",
|
||||
bot_api_version="6.6",
|
||||
)
|
||||
self.thumbnail_height: Optional[int] = warn_about_deprecated_arg_return_new_arg(
|
||||
deprecated_arg=thumb_height,
|
||||
new_arg=thumbnail_height,
|
||||
deprecated_arg_name="thumb_height",
|
||||
new_arg_name="thumbnail_height",
|
||||
bot_api_version="6.6",
|
||||
)
|
||||
|
||||
@property
|
||||
def thumb_url(self) -> Optional[str]:
|
||||
""":obj:`str`: Optional. Url of the thumbnail for the result.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbattributedeprecation| :attr:`thumbnail_url`.
|
||||
"""
|
||||
warn_about_deprecated_attr_in_property(
|
||||
deprecated_attr_name="thumb_url",
|
||||
new_attr_name="thumbnail_url",
|
||||
bot_api_version="6.6",
|
||||
)
|
||||
return self.thumbnail_url
|
||||
|
||||
@property
|
||||
def thumb_width(self) -> Optional[int]:
|
||||
""":obj:`str`: Optional. Thumbnail width.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbattributedeprecation| :attr:`thumbnail_width`.
|
||||
"""
|
||||
warn_about_deprecated_attr_in_property(
|
||||
deprecated_attr_name="thumb_width",
|
||||
new_attr_name="thumbnail_width",
|
||||
bot_api_version="6.6",
|
||||
)
|
||||
return self.thumbnail_width
|
||||
|
||||
@property
|
||||
def thumb_height(self) -> Optional[int]:
|
||||
""":obj:`str`: Optional. Thumbnail height.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbattributedeprecation| :attr:`thumbnail_height`.
|
||||
"""
|
||||
warn_about_deprecated_attr_in_property(
|
||||
deprecated_attr_name="thumb_height",
|
||||
new_attr_name="thumbnail_height",
|
||||
bot_api_version="6.6",
|
||||
)
|
||||
return self.thumbnail_height
|
||||
self.thumbnail_url: Optional[str] = thumbnail_url
|
||||
self.thumbnail_width: Optional[int] = thumbnail_width
|
||||
self.thumbnail_height: Optional[int] = thumbnail_height
|
||||
|
||||
@@ -25,10 +25,6 @@ from telegram._messageentity import MessageEntity
|
||||
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||
from telegram._utils.defaultvalue import DEFAULT_NONE
|
||||
from telegram._utils.types import JSONDict, ODVInput
|
||||
from telegram._utils.warnings_transition import (
|
||||
warn_about_deprecated_arg_return_new_arg,
|
||||
warn_about_deprecated_attr_in_property,
|
||||
)
|
||||
from telegram.constants import InlineQueryResultType
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@@ -44,6 +40,9 @@ class InlineQueryResultDocument(InlineQueryResult):
|
||||
|
||||
.. seealso:: :wiki:`Working with Files and Media <Working-with-Files-and-Media>`
|
||||
|
||||
.. versionchanged:: 20.5
|
||||
|removed_thumb_wildcard_note|
|
||||
|
||||
Args:
|
||||
id (:obj:`str`): Unique identifier for this result,
|
||||
:tg-const:`telegram.InlineQueryResult.MIN_ID_LENGTH`-
|
||||
@@ -66,18 +65,6 @@ class InlineQueryResultDocument(InlineQueryResult):
|
||||
to the message.
|
||||
input_message_content (:class:`telegram.InputMessageContent`, optional): Content of the
|
||||
message to be sent instead of the file.
|
||||
thumb_url (:obj:`str`, optional): URL of the thumbnail (JPEG only) for the file.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbargumentdeprecation| :paramref:`thumbnail_url`.
|
||||
thumb_width (:obj:`int`, optional): Thumbnail width.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbargumentdeprecation| :paramref:`thumbnail_width`.
|
||||
thumb_height (:obj:`int`, optional): Thumbnail height.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbargumentdeprecation| :paramref:`thumbnail_height`.
|
||||
thumbnail_url (:obj:`str`, optional): URL of the thumbnail (JPEG only) for the file.
|
||||
|
||||
.. versionadded:: 20.2
|
||||
@@ -150,9 +137,6 @@ class InlineQueryResultDocument(InlineQueryResult):
|
||||
description: Optional[str] = None,
|
||||
reply_markup: Optional[InlineKeyboardMarkup] = None,
|
||||
input_message_content: Optional["InputMessageContent"] = None,
|
||||
thumb_url: Optional[str] = None,
|
||||
thumb_width: Optional[int] = None,
|
||||
thumb_height: Optional[int] = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Optional[Sequence[MessageEntity]] = None,
|
||||
thumbnail_url: Optional[str] = None,
|
||||
@@ -175,66 +159,6 @@ class InlineQueryResultDocument(InlineQueryResult):
|
||||
self.description: Optional[str] = description
|
||||
self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup
|
||||
self.input_message_content: Optional[InputMessageContent] = input_message_content
|
||||
self.thumbnail_url: Optional[str] = warn_about_deprecated_arg_return_new_arg(
|
||||
deprecated_arg=thumb_url,
|
||||
new_arg=thumbnail_url,
|
||||
deprecated_arg_name="thumb_url",
|
||||
new_arg_name="thumbnail_url",
|
||||
bot_api_version="6.6",
|
||||
)
|
||||
self.thumbnail_width: Optional[int] = warn_about_deprecated_arg_return_new_arg(
|
||||
deprecated_arg=thumb_width,
|
||||
new_arg=thumbnail_width,
|
||||
deprecated_arg_name="thumb_width",
|
||||
new_arg_name="thumbnail_width",
|
||||
bot_api_version="6.6",
|
||||
)
|
||||
self.thumbnail_height: Optional[int] = warn_about_deprecated_arg_return_new_arg(
|
||||
deprecated_arg=thumb_height,
|
||||
new_arg=thumbnail_height,
|
||||
deprecated_arg_name="thumb_height",
|
||||
new_arg_name="thumbnail_height",
|
||||
bot_api_version="6.6",
|
||||
)
|
||||
|
||||
@property
|
||||
def thumb_url(self) -> Optional[str]:
|
||||
""":obj:`str`: Optional. URL of the thumbnail (JPEG only) for the file.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbattributedeprecation| :attr:`thumbnail_url`.
|
||||
"""
|
||||
warn_about_deprecated_attr_in_property(
|
||||
deprecated_attr_name="thumb_url",
|
||||
new_attr_name="thumbnail_url",
|
||||
bot_api_version="6.6",
|
||||
)
|
||||
return self.thumbnail_url
|
||||
|
||||
@property
|
||||
def thumb_width(self) -> Optional[int]:
|
||||
""":obj:`str`: Optional. Thumbnail width.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbattributedeprecation| :attr:`thumbnail_width`.
|
||||
"""
|
||||
warn_about_deprecated_attr_in_property(
|
||||
deprecated_attr_name="thumb_width",
|
||||
new_attr_name="thumbnail_width",
|
||||
bot_api_version="6.6",
|
||||
)
|
||||
return self.thumbnail_width
|
||||
|
||||
@property
|
||||
def thumb_height(self) -> Optional[int]:
|
||||
""":obj:`str`: Optional. Thumbnail height.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbattributedeprecation| :attr:`thumbnail_height`.
|
||||
"""
|
||||
warn_about_deprecated_attr_in_property(
|
||||
deprecated_attr_name="thumb_height",
|
||||
new_attr_name="thumbnail_height",
|
||||
bot_api_version="6.6",
|
||||
)
|
||||
return self.thumbnail_height
|
||||
self.thumbnail_url: Optional[str] = thumbnail_url
|
||||
self.thumbnail_width: Optional[int] = thumbnail_width
|
||||
self.thumbnail_height: Optional[int] = thumbnail_height
|
||||
|
||||
@@ -25,10 +25,6 @@ from telegram._messageentity import MessageEntity
|
||||
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||
from telegram._utils.defaultvalue import DEFAULT_NONE
|
||||
from telegram._utils.types import JSONDict, ODVInput
|
||||
from telegram._utils.warnings_transition import (
|
||||
warn_about_deprecated_arg_return_new_arg,
|
||||
warn_about_deprecated_attr_in_property,
|
||||
)
|
||||
from telegram.constants import InlineQueryResultType
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@@ -43,6 +39,9 @@ class InlineQueryResultGif(InlineQueryResult):
|
||||
|
||||
.. seealso:: :wiki:`Working with Files and Media <Working-with-Files-and-Media>`
|
||||
|
||||
.. versionchanged:: 20.5
|
||||
|removed_thumb_wildcard_note|
|
||||
|
||||
Args:
|
||||
id (:obj:`str`): Unique identifier for this result,
|
||||
:tg-const:`telegram.InlineQueryResult.MIN_ID_LENGTH`-
|
||||
@@ -79,16 +78,6 @@ class InlineQueryResultGif(InlineQueryResult):
|
||||
to the message.
|
||||
input_message_content (:class:`telegram.InputMessageContent`, optional): Content of the
|
||||
message to be sent instead of the GIF animation.
|
||||
thumb_mime_type (:obj:`str`, optional): MIME type of the thumbnail, must be one of
|
||||
``'image/jpeg'``, ``'image/gif'``, or ``'video/mp4'``. Defaults to ``'image/jpeg'``.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbargumentdeprecation| :paramref:`thumbnail_mime_type`.
|
||||
thumb_url (:obj:`str`, optional): URL of the static (JPEG or GIF) or animated (MPEG4)
|
||||
thumbnail for the result.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbargumentdeprecation| :paramref:`thumbnail_url`.
|
||||
|
||||
Raises:
|
||||
:class:`ValueError`: If neither :paramref:`thumbnail_url` nor :paramref:`thumb_url` is
|
||||
@@ -148,10 +137,7 @@ class InlineQueryResultGif(InlineQueryResult):
|
||||
self,
|
||||
id: str, # pylint: disable=redefined-builtin
|
||||
gif_url: str,
|
||||
# thumbnail_url is not optional in Telegram API, but we want to support thumb_url as well,
|
||||
# so thumbnail_url may not be passed. We will raise ValueError manually if neither
|
||||
# thumbnail_url nor thumb_url are passed
|
||||
thumbnail_url: Optional[str] = None,
|
||||
thumbnail_url: str,
|
||||
gif_width: Optional[int] = None,
|
||||
gif_height: Optional[int] = None,
|
||||
title: Optional[str] = None,
|
||||
@@ -160,31 +146,16 @@ class InlineQueryResultGif(InlineQueryResult):
|
||||
input_message_content: Optional["InputMessageContent"] = None,
|
||||
gif_duration: Optional[int] = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
thumb_mime_type: Optional[str] = None,
|
||||
caption_entities: Optional[Sequence[MessageEntity]] = None,
|
||||
thumbnail_mime_type: Optional[str] = None,
|
||||
# thumb_url is not optional in Telegram API, but it is here, along with thumbnail_url.
|
||||
thumb_url: Optional[str] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
if not (thumbnail_url or thumb_url):
|
||||
raise ValueError(
|
||||
"You must pass either 'thumbnail_url' or 'thumb_url'. Note that 'thumb_url' is "
|
||||
"deprecated."
|
||||
)
|
||||
|
||||
# Required
|
||||
super().__init__(InlineQueryResultType.GIF, id, api_kwargs=api_kwargs)
|
||||
with self._unfrozen():
|
||||
self.gif_url: str = gif_url
|
||||
self.thumbnail_url: str = warn_about_deprecated_arg_return_new_arg(
|
||||
deprecated_arg=thumb_url,
|
||||
new_arg=thumbnail_url,
|
||||
deprecated_arg_name="thumb_url",
|
||||
new_arg_name="thumbnail_url",
|
||||
bot_api_version="6.6",
|
||||
)
|
||||
self.thumbnail_url: str = thumbnail_url
|
||||
|
||||
# Optionals
|
||||
self.gif_width: Optional[int] = gif_width
|
||||
@@ -196,40 +167,4 @@ class InlineQueryResultGif(InlineQueryResult):
|
||||
self.caption_entities: Tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
|
||||
self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup
|
||||
self.input_message_content: Optional[InputMessageContent] = input_message_content
|
||||
self.thumbnail_mime_type: Optional[str] = warn_about_deprecated_arg_return_new_arg(
|
||||
deprecated_arg=thumb_mime_type,
|
||||
new_arg=thumbnail_mime_type,
|
||||
deprecated_arg_name="thumb_mime_type",
|
||||
new_arg_name="thumbnail_mime_type",
|
||||
bot_api_version="6.6",
|
||||
)
|
||||
|
||||
@property
|
||||
def thumb_url(self) -> str:
|
||||
""":obj:`str`: URL of the static (JPEG or GIF) or animated (MPEG4) thumbnail for the
|
||||
result.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbattributedeprecation| :attr:`thumbnail_url`.
|
||||
"""
|
||||
warn_about_deprecated_attr_in_property(
|
||||
deprecated_attr_name="thumb_url",
|
||||
new_attr_name="thumbnail_url",
|
||||
bot_api_version="6.6",
|
||||
)
|
||||
return self.thumbnail_url
|
||||
|
||||
@property
|
||||
def thumb_mime_type(self) -> Optional[str]:
|
||||
""":obj:`str`: Optional. Optional. MIME type of the thumbnail, must be one of
|
||||
``'image/jpeg'``, ``'image/gif'``, or ``'video/mp4'``. Defaults to ``'image/jpeg'``.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbattributedeprecation| :attr:`thumbnail_mime_type`.
|
||||
"""
|
||||
warn_about_deprecated_attr_in_property(
|
||||
deprecated_attr_name="thumb_mime_type",
|
||||
new_attr_name="thumbnail_mime_type",
|
||||
bot_api_version="6.6",
|
||||
)
|
||||
return self.thumbnail_mime_type
|
||||
self.thumbnail_mime_type: Optional[str] = thumbnail_mime_type
|
||||
|
||||
@@ -24,10 +24,6 @@ from telegram import constants
|
||||
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
|
||||
from telegram._inline.inlinequeryresult import InlineQueryResult
|
||||
from telegram._utils.types import JSONDict
|
||||
from telegram._utils.warnings_transition import (
|
||||
warn_about_deprecated_arg_return_new_arg,
|
||||
warn_about_deprecated_attr_in_property,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import InputMessageContent
|
||||
@@ -39,6 +35,9 @@ class InlineQueryResultLocation(InlineQueryResult):
|
||||
Alternatively, you can use :attr:`input_message_content` to send a message with the specified
|
||||
content instead of the location.
|
||||
|
||||
.. versionchanged:: 20.5
|
||||
|removed_thumb_wildcard_note|
|
||||
|
||||
Args:
|
||||
id (:obj:`str`): Unique identifier for this result,
|
||||
:tg-const:`telegram.InlineQueryResult.MIN_ID_LENGTH`-
|
||||
@@ -66,18 +65,6 @@ class InlineQueryResultLocation(InlineQueryResult):
|
||||
to the message.
|
||||
input_message_content (:class:`telegram.InputMessageContent`, optional): Content of the
|
||||
message to be sent instead of the location.
|
||||
thumb_url (:obj:`str`, optional): Url of the thumbnail for the result.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbargumentdeprecation| :paramref:`thumbnail_url`.
|
||||
thumb_width (:obj:`int`, optional): Thumbnail width.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbargumentdeprecation| :paramref:`thumbnail_width`.
|
||||
thumb_height (:obj:`int`, optional): Thumbnail height.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbargumentdeprecation| :paramref:`thumbnail_height`.
|
||||
thumbnail_url (:obj:`str`, optional): Url of the thumbnail for the result.
|
||||
|
||||
.. versionadded:: 20.2
|
||||
@@ -152,9 +139,6 @@ class InlineQueryResultLocation(InlineQueryResult):
|
||||
live_period: Optional[int] = None,
|
||||
reply_markup: Optional[InlineKeyboardMarkup] = None,
|
||||
input_message_content: Optional["InputMessageContent"] = None,
|
||||
thumb_url: Optional[str] = None,
|
||||
thumb_width: Optional[int] = None,
|
||||
thumb_height: Optional[int] = None,
|
||||
horizontal_accuracy: Optional[float] = None,
|
||||
heading: Optional[int] = None,
|
||||
proximity_alert_radius: Optional[int] = None,
|
||||
@@ -175,75 +159,15 @@ class InlineQueryResultLocation(InlineQueryResult):
|
||||
self.live_period: Optional[int] = live_period
|
||||
self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup
|
||||
self.input_message_content: Optional[InputMessageContent] = input_message_content
|
||||
self.thumbnail_url: Optional[str] = warn_about_deprecated_arg_return_new_arg(
|
||||
deprecated_arg=thumb_url,
|
||||
new_arg=thumbnail_url,
|
||||
deprecated_arg_name="thumb_url",
|
||||
new_arg_name="thumbnail_url",
|
||||
bot_api_version="6.6",
|
||||
)
|
||||
self.thumbnail_width: Optional[int] = warn_about_deprecated_arg_return_new_arg(
|
||||
deprecated_arg=thumb_width,
|
||||
new_arg=thumbnail_width,
|
||||
deprecated_arg_name="thumb_width",
|
||||
new_arg_name="thumbnail_width",
|
||||
bot_api_version="6.6",
|
||||
)
|
||||
self.thumbnail_height: Optional[int] = warn_about_deprecated_arg_return_new_arg(
|
||||
deprecated_arg=thumb_height,
|
||||
new_arg=thumbnail_height,
|
||||
deprecated_arg_name="thumb_height",
|
||||
new_arg_name="thumbnail_height",
|
||||
bot_api_version="6.6",
|
||||
)
|
||||
self.thumbnail_url: Optional[str] = thumbnail_url
|
||||
self.thumbnail_width: Optional[int] = thumbnail_width
|
||||
self.thumbnail_height: Optional[int] = thumbnail_height
|
||||
self.horizontal_accuracy: Optional[float] = horizontal_accuracy
|
||||
self.heading: Optional[int] = heading
|
||||
self.proximity_alert_radius: Optional[int] = (
|
||||
int(proximity_alert_radius) if proximity_alert_radius else None
|
||||
)
|
||||
|
||||
@property
|
||||
def thumb_url(self) -> Optional[str]:
|
||||
""":obj:`str`: Optional. Url of the thumbnail for the result.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbattributedeprecation| :attr:`thumbnail_url`.
|
||||
"""
|
||||
warn_about_deprecated_attr_in_property(
|
||||
deprecated_attr_name="thumb_url",
|
||||
new_attr_name="thumbnail_url",
|
||||
bot_api_version="6.6",
|
||||
)
|
||||
return self.thumbnail_url
|
||||
|
||||
@property
|
||||
def thumb_width(self) -> Optional[int]:
|
||||
""":obj:`str`: Optional. Thumbnail width.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbattributedeprecation| :attr:`thumbnail_width`.
|
||||
"""
|
||||
warn_about_deprecated_attr_in_property(
|
||||
deprecated_attr_name="thumb_width",
|
||||
new_attr_name="thumbnail_width",
|
||||
bot_api_version="6.6",
|
||||
)
|
||||
return self.thumbnail_width
|
||||
|
||||
@property
|
||||
def thumb_height(self) -> Optional[int]:
|
||||
""":obj:`str`: Optional. Thumbnail height.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbattributedeprecation| :attr:`thumbnail_height`.
|
||||
"""
|
||||
warn_about_deprecated_attr_in_property(
|
||||
deprecated_attr_name="thumb_height",
|
||||
new_attr_name="thumbnail_height",
|
||||
bot_api_version="6.6",
|
||||
)
|
||||
return self.thumbnail_height
|
||||
|
||||
HORIZONTAL_ACCURACY: Final[int] = constants.LocationLimit.HORIZONTAL_ACCURACY
|
||||
""":const:`telegram.constants.LocationLimit.HORIZONTAL_ACCURACY`
|
||||
|
||||
|
||||
@@ -25,10 +25,6 @@ from telegram._messageentity import MessageEntity
|
||||
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||
from telegram._utils.defaultvalue import DEFAULT_NONE
|
||||
from telegram._utils.types import JSONDict, ODVInput
|
||||
from telegram._utils.warnings_transition import (
|
||||
warn_about_deprecated_arg_return_new_arg,
|
||||
warn_about_deprecated_attr_in_property,
|
||||
)
|
||||
from telegram.constants import InlineQueryResultType
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@@ -44,6 +40,9 @@ class InlineQueryResultMpeg4Gif(InlineQueryResult):
|
||||
|
||||
.. seealso:: :wiki:`Working with Files and Media <Working-with-Files-and-Media>`
|
||||
|
||||
.. versionchanged:: 20.5
|
||||
|removed_thumb_wildcard_note|
|
||||
|
||||
Args:
|
||||
id (:obj:`str`): Unique identifier for this result,
|
||||
:tg-const:`telegram.InlineQueryResult.MIN_ID_LENGTH`-
|
||||
@@ -141,10 +140,7 @@ class InlineQueryResultMpeg4Gif(InlineQueryResult):
|
||||
self,
|
||||
id: str, # pylint: disable=redefined-builtin
|
||||
mpeg4_url: str,
|
||||
# thumbnail_url is not optional in Telegram API, but we want to support thumb_url as well,
|
||||
# so thumbnail_url may not be passed. We will raise ValueError manually if neither
|
||||
# thumbnail_url nor thumb_url are passed
|
||||
thumbnail_url: Optional[str] = None,
|
||||
thumbnail_url: str,
|
||||
mpeg4_width: Optional[int] = None,
|
||||
mpeg4_height: Optional[int] = None,
|
||||
title: Optional[str] = None,
|
||||
@@ -153,31 +149,16 @@ class InlineQueryResultMpeg4Gif(InlineQueryResult):
|
||||
input_message_content: Optional["InputMessageContent"] = None,
|
||||
mpeg4_duration: Optional[int] = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
thumb_mime_type: Optional[str] = None,
|
||||
caption_entities: Optional[Sequence[MessageEntity]] = None,
|
||||
thumbnail_mime_type: Optional[str] = None,
|
||||
# thumb_url is not optional in Telegram API, but it is here, along with thumbnail_url.
|
||||
thumb_url: Optional[str] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
if not (thumbnail_url or thumb_url):
|
||||
raise ValueError(
|
||||
"You must pass either 'thumbnail_url' or 'thumb_url'. Note that 'thumb_url' is "
|
||||
"deprecated."
|
||||
)
|
||||
|
||||
# Required
|
||||
super().__init__(InlineQueryResultType.MPEG4GIF, id, api_kwargs=api_kwargs)
|
||||
with self._unfrozen():
|
||||
self.mpeg4_url: str = mpeg4_url
|
||||
self.thumbnail_url: str = warn_about_deprecated_arg_return_new_arg(
|
||||
deprecated_arg=thumb_url,
|
||||
new_arg=thumbnail_url,
|
||||
deprecated_arg_name="thumb_url",
|
||||
new_arg_name="thumbnail_url",
|
||||
bot_api_version="6.6",
|
||||
)
|
||||
self.thumbnail_url: str = thumbnail_url
|
||||
|
||||
# Optional
|
||||
self.mpeg4_width: Optional[int] = mpeg4_width
|
||||
@@ -189,40 +170,4 @@ class InlineQueryResultMpeg4Gif(InlineQueryResult):
|
||||
self.caption_entities: Tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
|
||||
self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup
|
||||
self.input_message_content: Optional[InputMessageContent] = input_message_content
|
||||
self.thumbnail_mime_type: Optional[str] = warn_about_deprecated_arg_return_new_arg(
|
||||
deprecated_arg=thumb_mime_type,
|
||||
new_arg=thumbnail_mime_type,
|
||||
deprecated_arg_name="thumb_mime_type",
|
||||
new_arg_name="thumbnail_mime_type",
|
||||
bot_api_version="6.6",
|
||||
)
|
||||
|
||||
@property
|
||||
def thumb_url(self) -> str:
|
||||
""":obj:`str`: URL of the static (JPEG or GIF) or animated (MPEG4) thumbnail for the
|
||||
result.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbattributedeprecation| :attr:`thumbnail_url`.
|
||||
"""
|
||||
warn_about_deprecated_attr_in_property(
|
||||
deprecated_attr_name="thumb_url",
|
||||
new_attr_name="thumbnail_url",
|
||||
bot_api_version="6.6",
|
||||
)
|
||||
return self.thumbnail_url
|
||||
|
||||
@property
|
||||
def thumb_mime_type(self) -> Optional[str]:
|
||||
""":obj:`str`: Optional. Optional. MIME type of the thumbnail, must be one of
|
||||
``'image/jpeg'``, ``'image/gif'``, or ``'video/mp4'``. Defaults to ``'image/jpeg'``.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbattributedeprecation| :attr:`thumbnail_mime_type`.
|
||||
"""
|
||||
warn_about_deprecated_attr_in_property(
|
||||
deprecated_attr_name="thumb_mime_type",
|
||||
new_attr_name="thumbnail_mime_type",
|
||||
bot_api_version="6.6",
|
||||
)
|
||||
return self.thumbnail_mime_type
|
||||
self.thumbnail_mime_type: Optional[str] = thumbnail_mime_type
|
||||
|
||||
@@ -25,10 +25,6 @@ from telegram._messageentity import MessageEntity
|
||||
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||
from telegram._utils.defaultvalue import DEFAULT_NONE
|
||||
from telegram._utils.types import JSONDict, ODVInput
|
||||
from telegram._utils.warnings_transition import (
|
||||
warn_about_deprecated_arg_return_new_arg,
|
||||
warn_about_deprecated_attr_in_property,
|
||||
)
|
||||
from telegram.constants import InlineQueryResultType
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@@ -43,6 +39,9 @@ class InlineQueryResultPhoto(InlineQueryResult):
|
||||
|
||||
.. seealso:: :wiki:`Working with Files and Media <Working-with-Files-and-Media>`
|
||||
|
||||
.. versionchanged:: 20.5
|
||||
|removed_thumb_url_note|
|
||||
|
||||
Args:
|
||||
id (:obj:`str`): Unique identifier for this result,
|
||||
:tg-const:`telegram.InlineQueryResult.MIN_ID_LENGTH`-
|
||||
@@ -75,10 +74,6 @@ class InlineQueryResultPhoto(InlineQueryResult):
|
||||
to the message.
|
||||
input_message_content (:class:`telegram.InputMessageContent`, optional): Content of the
|
||||
message to be sent instead of the photo.
|
||||
thumb_url (:obj:`str`, optional): URL of the thumbnail for the photo.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbargumentdeprecation| :paramref:`thumbnail_url`.
|
||||
|
||||
Raises:
|
||||
:class:`ValueError`: If neither :paramref:`thumbnail_url` nor :paramref:`thumb_url` is
|
||||
@@ -131,10 +126,7 @@ class InlineQueryResultPhoto(InlineQueryResult):
|
||||
self,
|
||||
id: str, # pylint: disable=redefined-builtin
|
||||
photo_url: str,
|
||||
# thumbnail_url is not optional in Telegram API, but we want to support thumb_url as well,
|
||||
# so thumbnail_url may not be passed. We will raise ValueError manually if neither
|
||||
# thumbnail_url nor thumb_url are passed
|
||||
thumbnail_url: Optional[str] = None,
|
||||
thumbnail_url: str,
|
||||
photo_width: Optional[int] = None,
|
||||
photo_height: Optional[int] = None,
|
||||
title: Optional[str] = None,
|
||||
@@ -144,28 +136,14 @@ class InlineQueryResultPhoto(InlineQueryResult):
|
||||
input_message_content: Optional["InputMessageContent"] = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Optional[Sequence[MessageEntity]] = None,
|
||||
# thumb_url is not optional in Telegram API, but it is here, along with thumbnail_url.
|
||||
thumb_url: Optional[str] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
if not (thumbnail_url or thumb_url):
|
||||
raise ValueError(
|
||||
"You must pass either 'thumbnail_url' or 'thumb_url'. Note that 'thumb_url' is "
|
||||
"deprecated."
|
||||
)
|
||||
|
||||
# Required
|
||||
super().__init__(InlineQueryResultType.PHOTO, id, api_kwargs=api_kwargs)
|
||||
with self._unfrozen():
|
||||
self.photo_url: str = photo_url
|
||||
self.thumbnail_url: str = warn_about_deprecated_arg_return_new_arg(
|
||||
deprecated_arg=thumb_url,
|
||||
new_arg=thumbnail_url,
|
||||
deprecated_arg_name="thumb_url",
|
||||
new_arg_name="thumbnail_url",
|
||||
bot_api_version="6.6",
|
||||
)
|
||||
self.thumbnail_url: str = thumbnail_url
|
||||
|
||||
# Optionals
|
||||
self.photo_width: Optional[int] = photo_width
|
||||
@@ -177,17 +155,3 @@ class InlineQueryResultPhoto(InlineQueryResult):
|
||||
self.caption_entities: Tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
|
||||
self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup
|
||||
self.input_message_content: Optional[InputMessageContent] = input_message_content
|
||||
|
||||
@property
|
||||
def thumb_url(self) -> Optional[str]:
|
||||
""":obj:`str`: URL of the thumbnail for the photo.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbattributedeprecation| :attr:`thumbnail_url`.
|
||||
"""
|
||||
warn_about_deprecated_attr_in_property(
|
||||
deprecated_attr_name="thumb_url",
|
||||
new_attr_name="thumbnail_url",
|
||||
bot_api_version="6.6",
|
||||
)
|
||||
return self.thumbnail_url
|
||||
|
||||
@@ -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=redefined-builtin
|
||||
"""This module contains the class that represent a Telegram InlineQueryResultsButton."""
|
||||
|
||||
from typing import TYPE_CHECKING, Final, Optional
|
||||
@@ -43,7 +42,7 @@ class InlineQueryResultsButton(TelegramObject):
|
||||
`Web App <https://core.telegram.org/bots/webapps>`_ that will be launched when the
|
||||
user presses the button. The Web App will be able to switch back to the inline mode
|
||||
using the method
|
||||
`switchInlineQuery <https://core.telegram.org/bots/webapps#initializing-web-apps>`_
|
||||
`switchInlineQuery <https://core.telegram.org/bots/webapps#initializing-mini-apps>`_
|
||||
inside the Web App.
|
||||
start_parameter (:obj:`str`, optional): Deep-linking parameter for the
|
||||
:guilabel:`/start` message sent to the bot when user presses the switch button.
|
||||
|
||||
@@ -23,10 +23,6 @@ from typing import TYPE_CHECKING, Optional
|
||||
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
|
||||
from telegram._inline.inlinequeryresult import InlineQueryResult
|
||||
from telegram._utils.types import JSONDict
|
||||
from telegram._utils.warnings_transition import (
|
||||
warn_about_deprecated_arg_return_new_arg,
|
||||
warn_about_deprecated_attr_in_property,
|
||||
)
|
||||
from telegram.constants import InlineQueryResultType
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@@ -43,6 +39,9 @@ class InlineQueryResultVenue(InlineQueryResult):
|
||||
Foursquare details and Google Pace details are mutually exclusive. However, this
|
||||
behaviour is undocumented and might be changed by Telegram.
|
||||
|
||||
.. versionchanged:: 20.5
|
||||
|removed_thumb_wildcard_note|
|
||||
|
||||
Args:
|
||||
id (:obj:`str`): Unique identifier for this result,
|
||||
:tg-const:`telegram.InlineQueryResult.MIN_ID_LENGTH`-
|
||||
@@ -63,18 +62,6 @@ class InlineQueryResultVenue(InlineQueryResult):
|
||||
to the message.
|
||||
input_message_content (:class:`telegram.InputMessageContent`, optional): Content of the
|
||||
message to be sent instead of the venue.
|
||||
thumb_url (:obj:`str`, optional): Url of the thumbnail for the result.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbargumentdeprecation| :paramref:`thumbnail_url`.
|
||||
thumb_width (:obj:`int`, optional): Thumbnail width.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbargumentdeprecation| :paramref:`thumbnail_width`.
|
||||
thumb_height (:obj:`int`, optional): Thumbnail height.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbargumentdeprecation| :paramref:`thumbnail_height`.
|
||||
thumbnail_url (:obj:`str`, optional): Url of the thumbnail for the result.
|
||||
|
||||
.. versionadded:: 20.2
|
||||
@@ -145,9 +132,6 @@ class InlineQueryResultVenue(InlineQueryResult):
|
||||
foursquare_type: Optional[str] = None,
|
||||
reply_markup: Optional[InlineKeyboardMarkup] = None,
|
||||
input_message_content: Optional["InputMessageContent"] = None,
|
||||
thumb_url: Optional[str] = None,
|
||||
thumb_width: Optional[int] = None,
|
||||
thumb_height: Optional[int] = None,
|
||||
google_place_id: Optional[str] = None,
|
||||
google_place_type: Optional[str] = None,
|
||||
thumbnail_url: Optional[str] = None,
|
||||
@@ -171,66 +155,6 @@ class InlineQueryResultVenue(InlineQueryResult):
|
||||
self.google_place_type: Optional[str] = google_place_type
|
||||
self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup
|
||||
self.input_message_content: Optional[InputMessageContent] = input_message_content
|
||||
self.thumbnail_url: Optional[str] = warn_about_deprecated_arg_return_new_arg(
|
||||
deprecated_arg=thumb_url,
|
||||
new_arg=thumbnail_url,
|
||||
deprecated_arg_name="thumb_url",
|
||||
new_arg_name="thumbnail_url",
|
||||
bot_api_version="6.6",
|
||||
)
|
||||
self.thumbnail_width: Optional[int] = warn_about_deprecated_arg_return_new_arg(
|
||||
deprecated_arg=thumb_width,
|
||||
new_arg=thumbnail_width,
|
||||
deprecated_arg_name="thumb_width",
|
||||
new_arg_name="thumbnail_width",
|
||||
bot_api_version="6.6",
|
||||
)
|
||||
self.thumbnail_height: Optional[int] = warn_about_deprecated_arg_return_new_arg(
|
||||
deprecated_arg=thumb_height,
|
||||
new_arg=thumbnail_height,
|
||||
deprecated_arg_name="thumb_height",
|
||||
new_arg_name="thumbnail_height",
|
||||
bot_api_version="6.6",
|
||||
)
|
||||
|
||||
@property
|
||||
def thumb_url(self) -> Optional[str]:
|
||||
""":obj:`str`: Optional. Url of the thumbnail for the result.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbattributedeprecation| :attr:`thumbnail_url`.
|
||||
"""
|
||||
warn_about_deprecated_attr_in_property(
|
||||
deprecated_attr_name="thumb_url",
|
||||
new_attr_name="thumbnail_url",
|
||||
bot_api_version="6.6",
|
||||
)
|
||||
return self.thumbnail_url
|
||||
|
||||
@property
|
||||
def thumb_width(self) -> Optional[int]:
|
||||
""":obj:`str`: Optional. Thumbnail width.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbattributedeprecation| :attr:`thumbnail_width`.
|
||||
"""
|
||||
warn_about_deprecated_attr_in_property(
|
||||
deprecated_attr_name="thumb_width",
|
||||
new_attr_name="thumbnail_width",
|
||||
bot_api_version="6.6",
|
||||
)
|
||||
return self.thumbnail_width
|
||||
|
||||
@property
|
||||
def thumb_height(self) -> Optional[int]:
|
||||
""":obj:`str`: Optional. Thumbnail height.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbattributedeprecation| :attr:`thumbnail_height`.
|
||||
"""
|
||||
warn_about_deprecated_attr_in_property(
|
||||
deprecated_attr_name="thumb_height",
|
||||
new_attr_name="thumbnail_height",
|
||||
bot_api_version="6.6",
|
||||
)
|
||||
return self.thumbnail_height
|
||||
self.thumbnail_url: Optional[str] = thumbnail_url
|
||||
self.thumbnail_width: Optional[int] = thumbnail_width
|
||||
self.thumbnail_height: Optional[int] = thumbnail_height
|
||||
|
||||
@@ -25,10 +25,6 @@ from telegram._messageentity import MessageEntity
|
||||
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||
from telegram._utils.defaultvalue import DEFAULT_NONE
|
||||
from telegram._utils.types import JSONDict, ODVInput
|
||||
from telegram._utils.warnings_transition import (
|
||||
warn_about_deprecated_arg_return_new_arg,
|
||||
warn_about_deprecated_attr_in_property,
|
||||
)
|
||||
from telegram.constants import InlineQueryResultType
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@@ -48,6 +44,9 @@ class InlineQueryResultVideo(InlineQueryResult):
|
||||
|
||||
.. seealso:: :wiki:`Working with Files and Media <Working-with-Files-and-Media>`
|
||||
|
||||
.. versionchanged:: 20.5
|
||||
|removed_thumb_url_note|
|
||||
|
||||
Args:
|
||||
id (:obj:`str`): Unique identifier for this result,
|
||||
:tg-const:`telegram.InlineQueryResult.MIN_ID_LENGTH`-
|
||||
@@ -89,10 +88,6 @@ class InlineQueryResultVideo(InlineQueryResult):
|
||||
message to be sent instead of the video. This field is required if
|
||||
``InlineQueryResultVideo`` is used to send an HTML-page as a result
|
||||
(e.g., a YouTube video).
|
||||
thumb_url (:obj:`str`, optional): URL of the thumbnail (JPEG only) for the video.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbargumentdeprecation| :paramref:`thumbnail_url`.
|
||||
|
||||
Raises:
|
||||
:class:`ValueError`: If neither :paramref:`thumbnail_url` nor :paramref:`thumb_url` is
|
||||
@@ -156,13 +151,8 @@ class InlineQueryResultVideo(InlineQueryResult):
|
||||
id: str, # pylint: disable=redefined-builtin
|
||||
video_url: str,
|
||||
mime_type: str,
|
||||
# thumbnail_url and title are not optional in Telegram API, but we want to support
|
||||
# thumb_url as well, so thumbnail_url may not be passed if thumb_url is passed.
|
||||
# We will raise ValueError manually if neither thumbnail_url nor thumb_url are passed.
|
||||
thumbnail_url: Optional[str] = None,
|
||||
# title had to be made optional because of thumbnail_url. This is compensated by raising
|
||||
# TypeError manually if title is not passed.
|
||||
title: Optional[str] = None,
|
||||
thumbnail_url: str,
|
||||
title: str,
|
||||
caption: Optional[str] = None,
|
||||
video_width: Optional[int] = None,
|
||||
video_height: Optional[int] = None,
|
||||
@@ -172,35 +162,15 @@ class InlineQueryResultVideo(InlineQueryResult):
|
||||
input_message_content: Optional["InputMessageContent"] = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Optional[Sequence[MessageEntity]] = None,
|
||||
# thumb_url is not optional in Telegram API, but it is here, along with thumbnail_url.
|
||||
thumb_url: Optional[str] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
if not (thumbnail_url or thumb_url):
|
||||
raise ValueError(
|
||||
"You must pass either 'thumbnail_url' or 'thumb_url'. Note that 'thumb_url' is "
|
||||
"deprecated."
|
||||
)
|
||||
|
||||
if title is None:
|
||||
raise TypeError(
|
||||
"InlineQueryResultVideo.__init__() missing a required argument: you forgot to pass"
|
||||
" either 'title' or 'thumbnail_url'."
|
||||
)
|
||||
|
||||
# Required
|
||||
super().__init__(InlineQueryResultType.VIDEO, id, api_kwargs=api_kwargs)
|
||||
with self._unfrozen():
|
||||
self.video_url: str = video_url
|
||||
self.mime_type: str = mime_type
|
||||
self.thumbnail_url: str = warn_about_deprecated_arg_return_new_arg(
|
||||
deprecated_arg=thumb_url,
|
||||
new_arg=thumbnail_url,
|
||||
deprecated_arg_name="thumb_url",
|
||||
new_arg_name="thumbnail_url",
|
||||
bot_api_version="6.6",
|
||||
)
|
||||
self.thumbnail_url: str = thumbnail_url
|
||||
self.title: str = title
|
||||
|
||||
# Optional
|
||||
@@ -213,17 +183,3 @@ class InlineQueryResultVideo(InlineQueryResult):
|
||||
self.description: Optional[str] = description
|
||||
self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup
|
||||
self.input_message_content: Optional[InputMessageContent] = input_message_content
|
||||
|
||||
@property
|
||||
def thumb_url(self) -> str:
|
||||
""":obj:`str`: URL of the thumbnail (JPEG only) for the video.
|
||||
|
||||
.. deprecated:: 20.2
|
||||
|thumbattributedeprecation| :attr:`thumbnail_url`.
|
||||
"""
|
||||
warn_about_deprecated_attr_in_property(
|
||||
deprecated_attr_name="thumb_url",
|
||||
new_attr_name="thumbnail_url",
|
||||
bot_api_version="6.6",
|
||||
)
|
||||
return self.thumbnail_url
|
||||
|
||||
@@ -24,9 +24,7 @@ from telegram._keyboardbuttonpolltype import KeyboardButtonPollType
|
||||
from telegram._keyboardbuttonrequest import KeyboardButtonRequestChat, KeyboardButtonRequestUser
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._utils.types import JSONDict
|
||||
from telegram._utils.warnings import warn
|
||||
from telegram._webappinfo import WebAppInfo
|
||||
from telegram.warnings import PTBDeprecationWarning
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import Bot
|
||||
@@ -56,9 +54,9 @@ class KeyboardButton(TelegramObject):
|
||||
.. versionchanged:: 20.0
|
||||
:attr:`web_app` is considered as well when comparing objects of this type in terms of
|
||||
equality.
|
||||
.. deprecated:: 20.1
|
||||
:paramref:`request_user` and :paramref:`request_chat` will be considered as well when
|
||||
comparing objects of this type in terms of equality in V21.
|
||||
.. versionchanged:: 20.5
|
||||
:attr:`request_user` and :attr:`request_chat` are considered as well when
|
||||
comparing objects of this type in terms of equality.
|
||||
|
||||
Args:
|
||||
text (:obj:`str`): Text of the button. If none of the optional fields are used, it will be
|
||||
@@ -157,23 +155,12 @@ class KeyboardButton(TelegramObject):
|
||||
self.request_location,
|
||||
self.request_poll,
|
||||
self.web_app,
|
||||
self.request_user,
|
||||
self.request_chat,
|
||||
)
|
||||
|
||||
self._freeze()
|
||||
|
||||
def __eq__(self, other: object) -> bool:
|
||||
warn(
|
||||
"In v21, `request_user` and `request_chat` will be considered as well when comparing"
|
||||
" KeyboardButton instances.",
|
||||
PTBDeprecationWarning,
|
||||
stacklevel=2,
|
||||
)
|
||||
return super().__eq__(other)
|
||||
|
||||
def __hash__(self) -> int:
|
||||
# Intend: Added so support the own __eq__ function (which otherwise breaks hashing)
|
||||
return super().__hash__()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["KeyboardButton"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
|
||||
@@ -86,7 +86,7 @@ class LoginUrl(TelegramObject):
|
||||
def __init__(
|
||||
self,
|
||||
url: str,
|
||||
forward_text: Optional[bool] = None,
|
||||
forward_text: Optional[str] = None,
|
||||
bot_username: Optional[str] = None,
|
||||
request_write_access: Optional[bool] = None,
|
||||
*,
|
||||
@@ -96,7 +96,7 @@ class LoginUrl(TelegramObject):
|
||||
# Required
|
||||
self.url: str = url
|
||||
# Optional
|
||||
self.forward_text: Optional[bool] = forward_text
|
||||
self.forward_text: Optional[str] = forward_text
|
||||
self.bot_username: Optional[str] = bot_username
|
||||
self.request_write_access: Optional[bool] = request_write_access
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ class MenuButton(TelegramObject):
|
||||
if not data and cls is MenuButton:
|
||||
return None
|
||||
|
||||
_class_mapping: Dict[str, Type["MenuButton"]] = {
|
||||
_class_mapping: Dict[str, Type[MenuButton]] = {
|
||||
cls.COMMANDS: MenuButtonCommands,
|
||||
cls.WEB_APP: MenuButtonWebApp,
|
||||
cls.DEFAULT: MenuButtonDefault,
|
||||
|
||||
+49
-53
@@ -53,6 +53,7 @@ from telegram._payment.successfulpayment import SuccessfulPayment
|
||||
from telegram._poll import Poll
|
||||
from telegram._proximityalerttriggered import ProximityAlertTriggered
|
||||
from telegram._shared import ChatShared, UserShared
|
||||
from telegram._story import Story
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._user import User
|
||||
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||
@@ -67,7 +68,6 @@ from telegram._utils.types import (
|
||||
ODVInput,
|
||||
ReplyMarkup,
|
||||
)
|
||||
from telegram._utils.warnings import warn
|
||||
from telegram._videochat import (
|
||||
VideoChatEnded,
|
||||
VideoChatParticipantsInvited,
|
||||
@@ -78,7 +78,6 @@ from telegram._webappdata import WebAppData
|
||||
from telegram._writeaccessallowed import WriteAccessAllowed
|
||||
from telegram.constants import MessageAttachmentType, ParseMode
|
||||
from telegram.helpers import escape_markdown
|
||||
from telegram.warnings import PTBDeprecationWarning
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import (
|
||||
@@ -201,6 +200,9 @@ class Message(TelegramObject):
|
||||
|
||||
sticker (:class:`telegram.Sticker`, optional): Message is a sticker, information
|
||||
about the sticker.
|
||||
story (:class:`telegram.Story`, optional): Message is a forwarded story.
|
||||
|
||||
.. versionadded:: 20.5
|
||||
video (:class:`telegram.Video`, optional): Message is a video, information about the
|
||||
video.
|
||||
voice (:class:`telegram.Voice`, optional): Message is a voice message, information about
|
||||
@@ -328,7 +330,10 @@ class Message(TelegramObject):
|
||||
|
||||
.. versionadded:: 20.0
|
||||
write_access_allowed (:class:`telegram.WriteAccessAllowed`, optional): Service message:
|
||||
the user allowed the bot added to the attachment menu to write messages.
|
||||
the user allowed the bot to write messages after adding it to the attachment or side
|
||||
menu, launching a Web App from a link, or accepting an explicit request from a Web App
|
||||
sent by the method
|
||||
`requestWriteAccess <https://core.telegram.org/bots/webapps#initializing-mini-apps>`_.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
has_media_spoiler (:obj:`bool`, optional): :obj:`True`, if the message media is covered
|
||||
@@ -435,6 +440,9 @@ class Message(TelegramObject):
|
||||
about the sticker.
|
||||
|
||||
.. seealso:: :wiki:`Working with Files and Media <Working-with-Files-and-Media>`
|
||||
story (:class:`telegram.Story`): Optional. Message is a forwarded story.
|
||||
|
||||
.. versionadded:: 20.5
|
||||
video (:class:`telegram.Video`): Optional. Message is a video, information about the
|
||||
video.
|
||||
|
||||
@@ -591,10 +599,9 @@ class Message(TelegramObject):
|
||||
.. |custom_emoji_formatting_note| replace:: Custom emoji entities will be ignored by this
|
||||
function. Instead, the supplied replacement for the emoji will be used.
|
||||
|
||||
.. |custom_emoji_md1_deprecation| replace:: Since custom emoji entities are not supported by
|
||||
:attr:`~telegram.constants.ParseMode.MARKDOWN`, this method will raise a
|
||||
:exc:`ValueError` in future versions instead of falling back to the supplied replacement
|
||||
for the emoji.
|
||||
.. |custom_emoji_no_md1_support| replace:: Since custom emoji entities are not supported by
|
||||
:attr:`~telegram.constants.ParseMode.MARKDOWN`, this method now raises a
|
||||
:exc:`ValueError` when encountering a custom emoji.
|
||||
"""
|
||||
|
||||
# fmt: on
|
||||
@@ -671,6 +678,7 @@ class Message(TelegramObject):
|
||||
"has_media_spoiler",
|
||||
"user_shared",
|
||||
"chat_shared",
|
||||
"story",
|
||||
)
|
||||
|
||||
def __init__(
|
||||
@@ -746,6 +754,7 @@ class Message(TelegramObject):
|
||||
has_media_spoiler: Optional[bool] = None,
|
||||
user_shared: Optional[UserShared] = None,
|
||||
chat_shared: Optional[ChatShared] = None,
|
||||
story: Optional[Story] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
@@ -766,8 +775,8 @@ class Message(TelegramObject):
|
||||
self.edit_date: Optional[datetime.datetime] = edit_date
|
||||
self.has_protected_content: Optional[bool] = has_protected_content
|
||||
self.text: Optional[str] = text
|
||||
self.entities: Tuple["MessageEntity", ...] = parse_sequence_arg(entities)
|
||||
self.caption_entities: Tuple["MessageEntity", ...] = parse_sequence_arg(caption_entities)
|
||||
self.entities: Tuple[MessageEntity, ...] = parse_sequence_arg(entities)
|
||||
self.caption_entities: Tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
|
||||
self.audio: Optional[Audio] = audio
|
||||
self.game: Optional[Game] = game
|
||||
self.document: Optional[Document] = document
|
||||
@@ -834,6 +843,7 @@ class Message(TelegramObject):
|
||||
self.has_media_spoiler: Optional[bool] = has_media_spoiler
|
||||
self.user_shared: Optional[UserShared] = user_shared
|
||||
self.chat_shared: Optional[ChatShared] = chat_shared
|
||||
self.story: Optional[Story] = story
|
||||
|
||||
self._effective_attachment = DEFAULT_NONE
|
||||
|
||||
@@ -847,7 +857,7 @@ class Message(TelegramObject):
|
||||
return self.chat.id
|
||||
|
||||
@property
|
||||
def id(self) -> int: # pylint: disable=invalid-name
|
||||
def id(self) -> int:
|
||||
"""
|
||||
:obj:`int`: Shortcut for :attr:`message_id`.
|
||||
|
||||
@@ -903,6 +913,7 @@ class Message(TelegramObject):
|
||||
data["game"] = Game.de_json(data.get("game"), bot)
|
||||
data["photo"] = PhotoSize.de_list(data.get("photo"), bot)
|
||||
data["sticker"] = Sticker.de_json(data.get("sticker"), bot)
|
||||
data["story"] = Story.de_json(data.get("story"), bot)
|
||||
data["video"] = Video.de_json(data.get("video"), bot)
|
||||
data["voice"] = Voice.de_json(data.get("voice"), bot)
|
||||
data["video_note"] = VideoNote.de_json(data.get("video_note"), bot)
|
||||
@@ -973,6 +984,7 @@ class Message(TelegramObject):
|
||||
Sequence[PhotoSize],
|
||||
Poll,
|
||||
Sticker,
|
||||
Story,
|
||||
SuccessfulPayment,
|
||||
Venue,
|
||||
Video,
|
||||
@@ -995,6 +1007,7 @@ class Message(TelegramObject):
|
||||
* List[:class:`telegram.PhotoSize`]
|
||||
* :class:`telegram.Poll`
|
||||
* :class:`telegram.Sticker`
|
||||
* :class:`telegram.Story`
|
||||
* :class:`telegram.SuccessfulPayment`
|
||||
* :class:`telegram.Venue`
|
||||
* :class:`telegram.Video`
|
||||
@@ -1410,7 +1423,6 @@ class Message(TelegramObject):
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
reply_markup: Optional[ReplyMarkup] = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
thumb: Optional[FileInput] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
caption_entities: Optional[Sequence["MessageEntity"]] = None,
|
||||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -1452,7 +1464,6 @@ class Message(TelegramObject):
|
||||
reply_to_message_id=reply_to_message_id,
|
||||
reply_markup=reply_markup,
|
||||
parse_mode=parse_mode,
|
||||
thumb=thumb,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
caption_entities=caption_entities,
|
||||
filename=filename,
|
||||
@@ -1474,7 +1485,6 @@ class Message(TelegramObject):
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
reply_markup: Optional[ReplyMarkup] = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
thumb: Optional[FileInput] = None,
|
||||
disable_content_type_detection: Optional[bool] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
caption_entities: Optional[Sequence["MessageEntity"]] = None,
|
||||
@@ -1519,7 +1529,6 @@ class Message(TelegramObject):
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
parse_mode=parse_mode,
|
||||
thumb=thumb,
|
||||
api_kwargs=api_kwargs,
|
||||
disable_content_type_detection=disable_content_type_detection,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
@@ -1535,7 +1544,6 @@ class Message(TelegramObject):
|
||||
duration: Optional[int] = None,
|
||||
width: Optional[int] = None,
|
||||
height: Optional[int] = None,
|
||||
thumb: Optional[FileInput] = None,
|
||||
caption: Optional[str] = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
disable_notification: DVInput[bool] = DEFAULT_NONE,
|
||||
@@ -1579,7 +1587,6 @@ class Message(TelegramObject):
|
||||
duration=duration,
|
||||
width=width,
|
||||
height=height,
|
||||
thumb=thumb,
|
||||
caption=caption,
|
||||
parse_mode=parse_mode,
|
||||
disable_notification=disable_notification,
|
||||
@@ -1662,7 +1669,6 @@ class Message(TelegramObject):
|
||||
height: Optional[int] = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
supports_streaming: Optional[bool] = None,
|
||||
thumb: Optional[FileInput] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
caption_entities: Optional[Sequence["MessageEntity"]] = None,
|
||||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -1710,7 +1716,6 @@ class Message(TelegramObject):
|
||||
height=height,
|
||||
parse_mode=parse_mode,
|
||||
supports_streaming=supports_streaming,
|
||||
thumb=thumb,
|
||||
api_kwargs=api_kwargs,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
caption_entities=caption_entities,
|
||||
@@ -1729,7 +1734,6 @@ class Message(TelegramObject):
|
||||
disable_notification: DVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
reply_markup: Optional[ReplyMarkup] = None,
|
||||
thumb: Optional[FileInput] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
message_thread_id: Optional[int] = None,
|
||||
@@ -1772,7 +1776,6 @@ class Message(TelegramObject):
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
thumb=thumb,
|
||||
api_kwargs=api_kwargs,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
filename=filename,
|
||||
@@ -2504,7 +2507,7 @@ class Message(TelegramObject):
|
||||
text: str,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
disable_web_page_preview: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_markup: Optional[InlineKeyboardMarkup] = None,
|
||||
reply_markup: Optional["InlineKeyboardMarkup"] = None,
|
||||
entities: Optional[Sequence["MessageEntity"]] = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
@@ -2550,7 +2553,7 @@ class Message(TelegramObject):
|
||||
async def edit_caption(
|
||||
self,
|
||||
caption: Optional[str] = None,
|
||||
reply_markup: Optional[InlineKeyboardMarkup] = None,
|
||||
reply_markup: Optional["InlineKeyboardMarkup"] = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Optional[Sequence["MessageEntity"]] = None,
|
||||
*,
|
||||
@@ -2597,7 +2600,7 @@ class Message(TelegramObject):
|
||||
async def edit_media(
|
||||
self,
|
||||
media: "InputMedia",
|
||||
reply_markup: Optional[InlineKeyboardMarkup] = None,
|
||||
reply_markup: Optional["InlineKeyboardMarkup"] = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
@@ -2681,7 +2684,7 @@ class Message(TelegramObject):
|
||||
self,
|
||||
latitude: Optional[float] = None,
|
||||
longitude: Optional[float] = None,
|
||||
reply_markup: Optional[InlineKeyboardMarkup] = None,
|
||||
reply_markup: Optional["InlineKeyboardMarkup"] = None,
|
||||
horizontal_accuracy: Optional[float] = None,
|
||||
heading: Optional[int] = None,
|
||||
proximity_alert_radius: Optional[int] = None,
|
||||
@@ -2731,7 +2734,7 @@ class Message(TelegramObject):
|
||||
|
||||
async def stop_live_location(
|
||||
self,
|
||||
reply_markup: Optional[InlineKeyboardMarkup] = None,
|
||||
reply_markup: Optional["InlineKeyboardMarkup"] = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
@@ -2771,7 +2774,7 @@ class Message(TelegramObject):
|
||||
|
||||
async def set_game_score(
|
||||
self,
|
||||
user_id: Union[int, str],
|
||||
user_id: int,
|
||||
score: int,
|
||||
force: Optional[bool] = None,
|
||||
disable_edit_message: Optional[bool] = None,
|
||||
@@ -2816,7 +2819,7 @@ class Message(TelegramObject):
|
||||
|
||||
async def get_game_high_scores(
|
||||
self,
|
||||
user_id: Union[int, str],
|
||||
user_id: int,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
@@ -2886,7 +2889,7 @@ class Message(TelegramObject):
|
||||
|
||||
async def stop_poll(
|
||||
self,
|
||||
reply_markup: Optional[InlineKeyboardMarkup] = None,
|
||||
reply_markup: Optional["InlineKeyboardMarkup"] = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
@@ -3545,24 +3548,17 @@ class Message(TelegramObject):
|
||||
insert = f"||{escaped_text}||"
|
||||
elif entity.type == MessageEntity.CUSTOM_EMOJI:
|
||||
if version == 1:
|
||||
# this ensures compatibility to previous PTB versions
|
||||
insert = escaped_text
|
||||
warn(
|
||||
"Custom emoji entities are not supported for Markdown version 1. "
|
||||
"Future version of PTB will raise a ValueError instead of falling "
|
||||
"back to the alternative standard emoji.",
|
||||
stacklevel=3,
|
||||
category=PTBDeprecationWarning,
|
||||
raise ValueError(
|
||||
"Custom emoji entities are not supported for Markdown version 1"
|
||||
)
|
||||
else:
|
||||
# This should never be needed because ids are numeric but the documentation
|
||||
# specifically mentions it so here we are
|
||||
custom_emoji_id = escape_markdown(
|
||||
entity.custom_emoji_id,
|
||||
version=version,
|
||||
entity_type=MessageEntity.CUSTOM_EMOJI,
|
||||
)
|
||||
insert = f""
|
||||
# This should never be needed because ids are numeric but the documentation
|
||||
# specifically mentions it so here we are
|
||||
custom_emoji_id = escape_markdown(
|
||||
entity.custom_emoji_id,
|
||||
version=version,
|
||||
entity_type=MessageEntity.CUSTOM_EMOJI,
|
||||
)
|
||||
insert = f""
|
||||
else:
|
||||
insert = escaped_text
|
||||
|
||||
@@ -3611,8 +3607,8 @@ class Message(TelegramObject):
|
||||
|
||||
* |custom_emoji_formatting_note|
|
||||
|
||||
.. deprecated:: 20.3
|
||||
|custom_emoji_md1_deprecation|
|
||||
.. versionchanged:: 20.5
|
||||
|custom_emoji_no_md1_support|
|
||||
|
||||
Returns:
|
||||
:obj:`str`: Message text with entities formatted as Markdown.
|
||||
@@ -3658,8 +3654,8 @@ class Message(TelegramObject):
|
||||
|
||||
* |custom_emoji_formatting_note|
|
||||
|
||||
.. deprecated:: 20.3
|
||||
|custom_emoji_md1_deprecation|
|
||||
.. versionchanged:: 20.5
|
||||
|custom_emoji_no_md1_support|
|
||||
|
||||
Returns:
|
||||
:obj:`str`: Message text with entities formatted as Markdown.
|
||||
@@ -3705,8 +3701,8 @@ class Message(TelegramObject):
|
||||
|
||||
* |custom_emoji_formatting_note|
|
||||
|
||||
.. deprecated:: 20.3
|
||||
|custom_emoji_md1_deprecation|
|
||||
.. versionchanged:: 20.5
|
||||
|custom_emoji_no_md1_support|
|
||||
|
||||
Returns:
|
||||
:obj:`str`: Message caption with caption entities formatted as Markdown.
|
||||
@@ -3754,8 +3750,8 @@ class Message(TelegramObject):
|
||||
|
||||
* |custom_emoji_formatting_note|
|
||||
|
||||
.. deprecated:: 20.3
|
||||
|custom_emoji_md1_deprecation|
|
||||
.. versionchanged:: 20.5
|
||||
|custom_emoji_no_md1_support|
|
||||
|
||||
Returns:
|
||||
:obj:`str`: Message caption with caption entities formatted as Markdown.
|
||||
|
||||
+14
-10
@@ -40,11 +40,13 @@ class MessageEntity(TelegramObject):
|
||||
|
||||
Args:
|
||||
type (:obj:`str`): Type of the entity. Can be :attr:`MENTION` (@username),
|
||||
:attr:`HASHTAG`, :attr:`BOT_COMMAND`,
|
||||
:attr:`URL`, :attr:`EMAIL`, :attr:`PHONE_NUMBER`, :attr:`BOLD` (bold text),
|
||||
:attr:`ITALIC` (italic text), :attr:`STRIKETHROUGH`, :attr:`SPOILER` (spoiler message),
|
||||
:attr:`CODE` (monowidth string), :attr:`PRE` (monowidth block), :attr:`TEXT_LINK` (for
|
||||
clickable text URLs), :attr:`TEXT_MENTION` (for users without usernames),
|
||||
:attr:`HASHTAG` (#hashtag), :attr:`CASHTAG` ($USD), :attr:`BOT_COMMAND`
|
||||
(/start@jobs_bot), :attr:`URL` (https://telegram.org),
|
||||
:attr:`EMAIL` (do-not-reply@telegram.org), :attr:`PHONE_NUMBER` (+1-212-555-0123),
|
||||
:attr:`BOLD` (**bold text**), :attr:`ITALIC` (*italic text*), :attr:`UNDERLINE`
|
||||
(underlined text), :attr:`STRIKETHROUGH`, :attr:`SPOILER` (spoiler message),
|
||||
:attr:`CODE` (monowidth string), :attr:`PRE` (monowidth block), :attr:`TEXT_LINK`
|
||||
(for clickable text URLs), :attr:`TEXT_MENTION` (for users without usernames),
|
||||
:attr:`CUSTOM_EMOJI` (for inline custom emoji stickers).
|
||||
|
||||
.. versionadded:: 20.0
|
||||
@@ -64,11 +66,13 @@ class MessageEntity(TelegramObject):
|
||||
.. versionadded:: 20.0
|
||||
Attributes:
|
||||
type (:obj:`str`): Type of the entity. Can be :attr:`MENTION` (@username),
|
||||
:attr:`HASHTAG`, :attr:`BOT_COMMAND`,
|
||||
:attr:`URL`, :attr:`EMAIL`, :attr:`PHONE_NUMBER`, :attr:`BOLD` (bold text),
|
||||
:attr:`ITALIC` (italic text), :attr:`STRIKETHROUGH`, :attr:`SPOILER` (spoiler message),
|
||||
:attr:`CODE` (monowidth string), :attr:`PRE` (monowidth block), :attr:`TEXT_LINK` (for
|
||||
clickable text URLs), :attr:`TEXT_MENTION` (for users without usernames),
|
||||
:attr:`HASHTAG` (#hashtag), :attr:`CASHTAG` ($USD), :attr:`BOT_COMMAND`
|
||||
(/start@jobs_bot), :attr:`URL` (https://telegram.org),
|
||||
:attr:`EMAIL` (do-not-reply@telegram.org), :attr:`PHONE_NUMBER` (+1-212-555-0123),
|
||||
:attr:`BOLD` (**bold text**), :attr:`ITALIC` (*italic text*), :attr:`UNDERLINE`
|
||||
(underlined text), :attr:`STRIKETHROUGH`, :attr:`SPOILER` (spoiler message),
|
||||
:attr:`CODE` (monowidth string), :attr:`PRE` (monowidth block), :attr:`TEXT_LINK`
|
||||
(for clickable text URLs), :attr:`TEXT_MENTION` (for users without usernames),
|
||||
:attr:`CUSTOM_EMOJI` (for inline custom emoji stickers).
|
||||
|
||||
.. versionadded:: 20.0
|
||||
|
||||
@@ -154,7 +154,7 @@ class EncryptedCredentials(TelegramObject):
|
||||
self._id_attrs = (self.data, self.hash, self.secret)
|
||||
|
||||
self._decrypted_secret: Optional[str] = None
|
||||
self._decrypted_data: Optional["Credentials"] = None
|
||||
self._decrypted_data: Optional[Credentials] = None
|
||||
|
||||
self._freeze()
|
||||
|
||||
@@ -442,8 +442,8 @@ class SecureValue(TelegramObject):
|
||||
self.front_side: Optional[FileCredentials] = front_side
|
||||
self.reverse_side: Optional[FileCredentials] = reverse_side
|
||||
self.selfie: Optional[FileCredentials] = selfie
|
||||
self.files: Tuple["FileCredentials", ...] = parse_sequence_arg(files)
|
||||
self.translation: Tuple["FileCredentials", ...] = parse_sequence_arg(translation)
|
||||
self.files: Tuple[FileCredentials, ...] = parse_sequence_arg(files)
|
||||
self.translation: Tuple[FileCredentials, ...] = parse_sequence_arg(translation)
|
||||
|
||||
self._freeze()
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram EncryptedPassportElement."""
|
||||
from base64 import b64decode
|
||||
from typing import TYPE_CHECKING, Optional, Sequence, Tuple
|
||||
from typing import TYPE_CHECKING, Optional, Sequence, Tuple, Union
|
||||
|
||||
from telegram._passport.credentials import decrypt_json
|
||||
from telegram._passport.data import IdDocumentData, PersonalDetails, ResidentialAddress
|
||||
@@ -54,7 +54,7 @@ class EncryptedPassportElement(TelegramObject):
|
||||
data (:class:`telegram.PersonalDetails` | :class:`telegram.IdDocumentData` | \
|
||||
:class:`telegram.ResidentialAddress` | :obj:`str`, optional):
|
||||
Decrypted or encrypted data, available for "personal_details", "passport",
|
||||
"driver_license", "identity_card", "identity_passport" and "address" types.
|
||||
"driver_license", "identity_card", "internal_passport" and "address" types.
|
||||
phone_number (:obj:`str`, optional): User's verified phone number, available only for
|
||||
"phone_number" type.
|
||||
email (:obj:`str`, optional): User's verified email address, available only for "email"
|
||||
@@ -96,7 +96,7 @@ class EncryptedPassportElement(TelegramObject):
|
||||
data (:class:`telegram.PersonalDetails` | :class:`telegram.IdDocumentData` | \
|
||||
:class:`telegram.ResidentialAddress` | :obj:`str`):
|
||||
Optional. Decrypted or encrypted data, available for "personal_details", "passport",
|
||||
"driver_license", "identity_card", "identity_passport" and "address" types.
|
||||
"driver_license", "identity_card", "internal_passport" and "address" types.
|
||||
phone_number (:obj:`str`): Optional. User's verified phone number, available only for
|
||||
"phone_number" type.
|
||||
email (:obj:`str`): Optional. User's verified email address, available only for "email"
|
||||
@@ -151,7 +151,7 @@ class EncryptedPassportElement(TelegramObject):
|
||||
self,
|
||||
type: str, # pylint: disable=redefined-builtin
|
||||
hash: str, # pylint: disable=redefined-builtin
|
||||
data: Optional[PersonalDetails] = None,
|
||||
data: Optional[Union[PersonalDetails, IdDocumentData, ResidentialAddress]] = None,
|
||||
phone_number: Optional[str] = None,
|
||||
email: Optional[str] = None,
|
||||
files: Optional[Sequence[PassportFile]] = None,
|
||||
@@ -168,7 +168,7 @@ class EncryptedPassportElement(TelegramObject):
|
||||
# Required
|
||||
self.type: str = type
|
||||
# Optionals
|
||||
self.data: Optional[PersonalDetails] = data
|
||||
self.data: Optional[Union[PersonalDetails, IdDocumentData, ResidentialAddress]] = data
|
||||
self.phone_number: Optional[str] = phone_number
|
||||
self.email: Optional[str] = email
|
||||
self.files: Tuple[PassportFile, ...] = parse_sequence_arg(files)
|
||||
|
||||
@@ -19,10 +19,12 @@
|
||||
# pylint: disable=redefined-builtin
|
||||
"""This module contains the classes that represent Telegram PassportElementError."""
|
||||
|
||||
from typing import Optional
|
||||
from typing import List, Optional
|
||||
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._utils.types import JSONDict
|
||||
from telegram._utils.warnings import warn
|
||||
from telegram.warnings import PTBDeprecationWarning
|
||||
|
||||
|
||||
class PassportElementError(TelegramObject):
|
||||
@@ -173,23 +175,48 @@ class PassportElementErrorFiles(PassportElementError):
|
||||
type (:obj:`str`): The section of the user's Telegram Passport which has the issue, one of
|
||||
``"utility_bill"``, ``"bank_statement"``, ``"rental_agreement"``,
|
||||
``"passport_registration"``, ``"temporary_registration"``.
|
||||
file_hashes (List[:obj:`str`]): List of base64-encoded file hashes.
|
||||
message (:obj:`str`): Error message.
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = ("file_hashes",)
|
||||
__slots__ = ("_file_hashes",)
|
||||
|
||||
def __init__(
|
||||
self, type: str, file_hashes: str, message: str, *, api_kwargs: Optional[JSONDict] = None
|
||||
self,
|
||||
type: str,
|
||||
file_hashes: List[str],
|
||||
message: str,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
# Required
|
||||
super().__init__("files", type, message, api_kwargs=api_kwargs)
|
||||
with self._unfrozen():
|
||||
self.file_hashes: str = file_hashes
|
||||
self._file_hashes: List[str] = file_hashes
|
||||
|
||||
self._id_attrs = (self.source, self.type, self.message, *tuple(file_hashes))
|
||||
|
||||
def to_dict(self, recursive: bool = True) -> JSONDict:
|
||||
"""See :meth:`telegram.TelegramObject.to_dict` for details."""
|
||||
data = super().to_dict(recursive)
|
||||
data["file_hashes"] = self._file_hashes
|
||||
return data
|
||||
|
||||
@property
|
||||
def file_hashes(self) -> List[str]:
|
||||
"""List of base64-encoded file hashes.
|
||||
|
||||
.. deprecated:: 20.6
|
||||
This attribute will return a tuple instead of a list in future major versions.
|
||||
"""
|
||||
warn(
|
||||
"The attribute `file_hashes` will return a tuple instead of a list in future major"
|
||||
" versions.",
|
||||
PTBDeprecationWarning,
|
||||
stacklevel=2,
|
||||
)
|
||||
return self._file_hashes
|
||||
|
||||
|
||||
class PassportElementErrorFrontSide(PassportElementError):
|
||||
"""
|
||||
@@ -365,23 +392,49 @@ class PassportElementErrorTranslationFiles(PassportElementError):
|
||||
one of ``"passport"``, ``"driver_license"``, ``"identity_card"``,
|
||||
``"internal_passport"``, ``"utility_bill"``, ``"bank_statement"``,
|
||||
``"rental_agreement"``, ``"passport_registration"``, ``"temporary_registration"``.
|
||||
file_hashes (List[:obj:`str`]): List of base64-encoded file hashes.
|
||||
message (:obj:`str`): Error message.
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = ("file_hashes",)
|
||||
__slots__ = ("_file_hashes",)
|
||||
|
||||
def __init__(
|
||||
self, type: str, file_hashes: str, message: str, *, api_kwargs: Optional[JSONDict] = None
|
||||
self,
|
||||
type: str,
|
||||
file_hashes: List[str],
|
||||
message: str,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
# Required
|
||||
super().__init__("translation_files", type, message, api_kwargs=api_kwargs)
|
||||
with self._unfrozen():
|
||||
self.file_hashes: str = file_hashes
|
||||
self._file_hashes: List[str] = file_hashes
|
||||
|
||||
self._id_attrs = (self.source, self.type, self.message, *tuple(file_hashes))
|
||||
|
||||
def to_dict(self, recursive: bool = True) -> JSONDict:
|
||||
"""See :meth:`telegram.TelegramObject.to_dict` for details."""
|
||||
data = super().to_dict(recursive)
|
||||
data["file_hashes"] = self._file_hashes
|
||||
return data
|
||||
|
||||
@property
|
||||
def file_hashes(self) -> List[str]:
|
||||
"""List of base64-encoded file hashes.
|
||||
|
||||
.. deprecated:: 20.6
|
||||
This attribute will return a tuple instead of a list in future major versions.
|
||||
"""
|
||||
warn(
|
||||
"The attribute `file_hashes` will return a tuple instead of a list in future major"
|
||||
" versions. See the stability policy:"
|
||||
" https://docs.python-telegram-bot.org/en/stable/stability_policy.html",
|
||||
PTBDeprecationWarning,
|
||||
stacklevel=2,
|
||||
)
|
||||
return self._file_hashes
|
||||
|
||||
|
||||
class PassportElementErrorUnspecified(PassportElementError):
|
||||
"""
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user