mirror of
https://github.com/python-telegram-bot/python-telegram-bot.git
synced 2026-06-19 15:45:13 +00:00
Compare commits
48 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a9f6afd015 | |||
| 78c945d485 | |||
| 9e70ac8b7a | |||
| cf728496e4 | |||
| 078d775250 | |||
| 57298aa076 | |||
| 2c299bb109 | |||
| c1c5438f37 | |||
| 6ba7a097f4 | |||
| 6fc45a803d | |||
| 512a0b7417 | |||
| 7d952d8707 | |||
| b496fabf62 | |||
| 637b8e260b | |||
| 912fe45d8c | |||
| 805b7bff32 | |||
| f3bd0f1462 | |||
| 5b0e0b5f78 | |||
| c4623c4476 | |||
| ee6e82d7ad | |||
| c34f4811ea | |||
| d768abdd6b | |||
| 2561ffd16b | |||
| 622fdf7fa3 | |||
| 615f1bf20b | |||
| 7a8b1be5a4 | |||
| 3a8ace2e8b | |||
| 169bd47de3 | |||
| a956dcc6a4 | |||
| ee88973fee | |||
| 8f9fc65be0 | |||
| 75d946e4be | |||
| fed8d8875e | |||
| 42b68f1a70 | |||
| 58b8ef4ce4 | |||
| f6d009d3ac | |||
| 153894728c | |||
| 5fa457974d | |||
| 3ec7bb819c | |||
| 040cd2c2fc | |||
| 474f9c9693 | |||
| e18ca0d5e1 | |||
| 7331fff3fc | |||
| 23536ee759 | |||
| 2d8d43f2a5 | |||
| 8a542e22a0 | |||
| c0716dd344 | |||
| 668b49b048 |
@@ -157,7 +157,7 @@ Check-list for PRs
|
||||
This checklist is a non-exhaustive reminder of things that should be done before a PR is merged, both for you as contributor and for the maintainers.
|
||||
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.
|
||||
|
||||
- Added ``.. versionadded:: NEXT.VERSION``, ``.. versionchanged:: NEXT.VERSION`` or ``.. deprecated:: NEXT.VERSION`` to the docstrings for user facing changes (for methods/class descriptions, arguments and attributes)
|
||||
- Added ``.. versionadded:: NEXT.VERSION``, ``.. versionchanged:: NEXT.VERSION``, ``.. deprecated:: NEXT.VERSION`` or ``.. versionremoved:: NEXT.VERSION`` to the docstrings for user facing changes (for methods/class descriptions, arguments and attributes)
|
||||
- Created new or adapted existing unit tests
|
||||
- Documented code changes according to the `CSI standard <https://standards.mousepawmedia.com/en/stable/csi.html>`__
|
||||
- Added myself alphabetically to ``AUTHORS.rst`` (optional)
|
||||
@@ -276,7 +276,7 @@ This gives us the flexibility to re-order arguments and more importantly
|
||||
to add new required arguments. It's also more explicit and easier to read.
|
||||
|
||||
|
||||
.. _`Code of Conduct`: https://www.python.org/psf/conduct/
|
||||
.. _`Code of Conduct`: https://policies.python.org/python.org/code-of-conduct/
|
||||
.. _`issue tracker`: https://github.com/python-telegram-bot/python-telegram-bot/issues
|
||||
.. _`Telegram group`: https://telegram.me/pythontelegrambotgroup
|
||||
.. _`PEP 8 Style Guide`: https://peps.python.org/pep-0008/
|
||||
|
||||
@@ -12,6 +12,8 @@ body:
|
||||
To make it easier for us to help you, please read this [article](https://github.com/python-telegram-bot/python-telegram-bot/wiki/Ask-Right).
|
||||
|
||||
Please mind that there is also a users' [Telegram group](https://t.me/pythontelegrambotgroup) for questions about the library. Questions asked there might be answered quicker than here. Moreover, [GitHub Discussions](https://github.com/python-telegram-bot/python-telegram-bot/discussions) offer a slightly better format to discuss usage questions.
|
||||
|
||||
If you have asked the same question elsewhere (e.g. the [Telegram group](https://t.me/pythontelegrambotgroup) or [StackOverflow](https://stackoverflow.com/questions/tagged/python-telegram-bot)), provide a link to that thread.
|
||||
|
||||
- type: textarea
|
||||
id: issue-faced
|
||||
|
||||
@@ -16,7 +16,7 @@ jobs:
|
||||
|
||||
- name: Fetch Dependabot metadata
|
||||
id: dependabot-metadata
|
||||
uses: dependabot/fetch-metadata@v1.6.0
|
||||
uses: dependabot/fetch-metadata@v2.1.0
|
||||
|
||||
- uses: actions/checkout@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.10.0
|
||||
- uses: srvaroa/labeler@v1.10.1
|
||||
# Config file at .github/labeler.yml
|
||||
env:
|
||||
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
||||
|
||||
@@ -6,6 +6,7 @@ on:
|
||||
- tests/**
|
||||
- requirements.txt
|
||||
- requirements-opts.txt
|
||||
- requirements-dev.txt
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
|
||||
ci:
|
||||
autofix_prs: false
|
||||
autoupdate_schedule: monthly
|
||||
autoupdate_schedule: quarterly
|
||||
autoupdate_commit_msg: 'Bump `pre-commit` Hooks to Latest Versions'
|
||||
|
||||
repos:
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
rev: 'v0.2.1'
|
||||
rev: 'v0.4.3'
|
||||
hooks:
|
||||
- id: ruff
|
||||
name: ruff
|
||||
@@ -17,7 +18,7 @@ repos:
|
||||
- cachetools~=5.3.3
|
||||
- aiolimiter~=1.1.0
|
||||
- repo: https://github.com/psf/black-pre-commit-mirror
|
||||
rev: 24.1.1
|
||||
rev: 24.4.2
|
||||
hooks:
|
||||
- id: black
|
||||
args:
|
||||
@@ -28,7 +29,7 @@ repos:
|
||||
hooks:
|
||||
- id: flake8
|
||||
- repo: https://github.com/PyCQA/pylint
|
||||
rev: v3.0.3
|
||||
rev: v3.1.0
|
||||
hooks:
|
||||
- id: pylint
|
||||
files: ^(?!(tests|docs)).*\.py$
|
||||
@@ -40,7 +41,7 @@ repos:
|
||||
- aiolimiter~=1.1.0
|
||||
- . # this basically does `pip install -e .`
|
||||
- repo: https://github.com/pre-commit/mirrors-mypy
|
||||
rev: v1.8.0
|
||||
rev: v1.10.0
|
||||
hooks:
|
||||
- id: mypy
|
||||
name: mypy-ptb
|
||||
@@ -67,7 +68,7 @@ repos:
|
||||
- cachetools~=5.3.3
|
||||
- . # this basically does `pip install -e .`
|
||||
- repo: https://github.com/asottile/pyupgrade
|
||||
rev: v3.15.0
|
||||
rev: v3.15.2
|
||||
hooks:
|
||||
- id: pyupgrade
|
||||
args:
|
||||
|
||||
@@ -123,6 +123,7 @@ The following wonderful people contributed directly or indirectly to this projec
|
||||
- `Vorobjev Simon <https://github.com/simonvorobjev>`_
|
||||
- `Wagner Macedo <https://github.com/wagnerluis1982>`_
|
||||
- `wjt <https://github.com/wjt>`_
|
||||
- `Wonseok Oh <https://github.com/marinelay>`_
|
||||
- `Yaw Danso <https://github.com/dglitxh>`_
|
||||
- `Yao Kuan <https://github.com/thatguylah>`_
|
||||
- `zeroone2numeral2 <https://github.com/zeroone2numeral2>`_
|
||||
|
||||
+160
@@ -4,6 +4,166 @@
|
||||
Changelog
|
||||
=========
|
||||
|
||||
Version 21.3
|
||||
============
|
||||
*Released 2024-06-07*
|
||||
|
||||
This is the technical changelog for version 21.3. More elaborate release notes can be found in the news channel `@pythontelegrambotchannel <https://t.me/pythontelegrambotchannel>`_.
|
||||
|
||||
Major Changes
|
||||
-------------
|
||||
|
||||
- Full Support for Bot API 7.4 (:pr:`4286`, :pr:`4276` closes :issue:`4275`, :pr:`4285`, :pr:`4283`, :pr:`4280`, :pr:`4278`, :pr:`4279`)
|
||||
- Deprecate ``python-telegram-bot-raw`` (:pr:`4270`)
|
||||
- Remove Functionality Deprecated in Bot API 7.3 (:pr:`4266` closes :issue:`4244`)
|
||||
|
||||
New Features
|
||||
------------
|
||||
|
||||
- Add Parameter ``chat_id`` to ``ChatMemberHandler`` (:pr:`4290` by `uniquetrij <https://github.com/uniquetrij>`_ closes :issue:`4287`)
|
||||
|
||||
Documentation Improvements
|
||||
--------------------------
|
||||
|
||||
- Documentation Improvements (:pr:`4264` closes :issue:`4240`)
|
||||
|
||||
Internal Changes
|
||||
----------------
|
||||
|
||||
- Add ``setuptools`` to ``requirements-dev.txt`` (:pr:`4282`)
|
||||
- Update Settings for pre-commit.ci (:pr:`4265`)
|
||||
|
||||
Dependency Updates
|
||||
------------------
|
||||
|
||||
- Bump ``pytest`` from 8.2.0 to 8.2.1 (:pr:`4272`)
|
||||
|
||||
Version 21.2
|
||||
============
|
||||
|
||||
*Released 2024-05-20*
|
||||
|
||||
This is the technical changelog for version 21.2. More elaborate release notes can be found in the news channel `@pythontelegrambotchannel <https://t.me/pythontelegrambotchannel>`_.
|
||||
|
||||
Major Changes
|
||||
-------------
|
||||
|
||||
- Full Support for Bot API 7.3 (:pr:`4246`, :pr:`4260`, :pr:`4243`, :pr:`4248`, :pr:`4242` closes :issue:`4236`, :pr:`4247` by `aelkheir <https://github.com/aelkheir>`_)
|
||||
- Remove Functionality Deprecated by Bot API 7.2 (:pr:`4245`)
|
||||
|
||||
New Features
|
||||
------------
|
||||
|
||||
- Add Version to ``PTBDeprecationWarning`` (:pr:`4262` closes :issue:`4261`)
|
||||
- Handle Exceptions in building ``CallbackContext`` (:pr:`4222`)
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- Call ``Application.post_stop`` Only if ``Application.stop`` was called (:pr:`4211` closes :issue:`4210`)
|
||||
- Handle ``SystemExit`` raised in Handlers (:pr:`4157` closes :issue:`4155` and :issue:`4156`)
|
||||
- Make ``Birthdate.to_date`` Return a ``datetime.date`` Object (:pr:`4251`)
|
||||
|
||||
Documentation Improvements
|
||||
--------------------------
|
||||
|
||||
- Documentation Improvements (:pr:`4217`)
|
||||
|
||||
Internal Changes
|
||||
----------------
|
||||
|
||||
- Add New Rules to ``ruff`` Config (:pr:`4250`)
|
||||
- Adapt Test Suite to Changes in Error Messages (:pr:`4238`)
|
||||
|
||||
Dependency Updates
|
||||
------------------
|
||||
|
||||
- Bump ``furo`` from 2024.4.27 to 2024.5.6 (:pr:`4252`)
|
||||
- ``pre-commit`` autoupdate (:pr:`4239`)
|
||||
- Bump ``pytest`` from 8.1.1 to 8.2.0 (:pr:`4231`)
|
||||
- Bump ``dependabot/fetch-metadata`` from 2.0.0 to 2.1.0 (:pr:`4228`)
|
||||
- Bump ``pytest-asyncio`` from 0.21.1 to 0.21.2 (:pr:`4232`)
|
||||
- Bump ``pytest-xdist`` from 3.6.0 to 3.6.1 (:pr:`4233`)
|
||||
- Bump ``furo`` from 2024.1.29 to 2024.4.27 (:pr:`4230`)
|
||||
- Bump ``srvaroa/labeler`` from 1.10.0 to 1.10.1 (:pr:`4227`)
|
||||
- Bump ``pytest`` from 7.4.4 to 8.1.1 (:pr:`4218`)
|
||||
- Bump ``sphinx`` from 7.2.6 to 7.3.7 (:pr:`4215`)
|
||||
- Bump ``pytest-xdist`` from 3.5.0 to 3.6.0 (:pr:`4215`)
|
||||
|
||||
Version 21.1.1
|
||||
==============
|
||||
|
||||
*Released 2024-04-15*
|
||||
|
||||
This is the technical changelog for version 21.1.1. More elaborate release notes can be found in the news channel `@pythontelegrambotchannel <https://t.me/pythontelegrambotchannel>`__.
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- Fix Bug With Parameter ``message_thread_id`` of ``Message.reply_*`` (:pr:`4207` closes :issue:`4205`)
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- Remove Deprecation Warning in ``JobQueue.run_daily`` (:pr:`4206` by `@Konano <https://github.com/Konano>`__)
|
||||
- Fix Annotation of ``EncryptedCredentials.decrypted_secret`` (:pr:`4199` by `@marinelay <https://github.com/marinelay>`__ closes :issue:`4198`)
|
||||
|
||||
|
||||
Version 21.1
|
||||
==============
|
||||
|
||||
*Released 2024-04-12*
|
||||
|
||||
This is the technical changelog for version 21.1. More elaborate release notes can be found in the news channel `@pythontelegrambotchannel <https://t.me/pythontelegrambotchannel>`__.
|
||||
|
||||
Major Changes
|
||||
-------------
|
||||
|
||||
- API 7.2 (:pr:`4180` closes :issue:`4179` and :issue:`4181`, :issue:`4181`)
|
||||
- Make ``ChatAdministratorRights/ChatMemberAdministrator.can_*_stories`` Required (API 7.1) (:pr:`4192`)
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- Refactor Debug logging in ``Bot`` to Improve Type Hinting (:pr:`4151` closes :issue:`4010`)
|
||||
|
||||
New Features
|
||||
------------
|
||||
|
||||
- Make ``Message.reply_*`` Reply in the Same Topic by Default (:pr:`4170` by `@aelkheir <https://github.com/aelkheir>`__ closes :issue:`4139`)
|
||||
- Accept Socket Objects for Webhooks (:pr:`4161` closes :issue:`4078`)
|
||||
- Add ``Update.effective_sender`` (:pr:`4168` by `@aelkheir <https://github.com/aelkheir>`__ closes :issue:`4085`)
|
||||
|
||||
Documentation Improvements
|
||||
--------------------------
|
||||
|
||||
- Documentation Improvements (:pr:`4171`, :pr:`4158` by `@teslaedison <https://github.com/teslaedison>`__)
|
||||
|
||||
Internal Changes
|
||||
----------------
|
||||
|
||||
- Temporarily Mark Tests with ``get_sticker_set`` as XFAIL due to API 7.2 Update (:pr:`4190`)
|
||||
|
||||
Dependency Updates
|
||||
------------------
|
||||
|
||||
- ``pre-commit`` autoupdate (:pr:`4184`)
|
||||
- Bump ``dependabot/fetch-metadata`` from 1.6.0 to 2.0.0 (:pr:`4185`)
|
||||
|
||||
|
||||
Version 21.0.1
|
||||
==============
|
||||
|
||||
*Released 2024-03-06*
|
||||
|
||||
This is the technical changelog for version 21.0.1. More elaborate release notes can be found in the news channel `@pythontelegrambotchannel <https://t.me/pythontelegrambotchannel>`__.
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- Remove ``docs`` from Package (:pr:`4150`)
|
||||
|
||||
|
||||
Version 21.0
|
||||
============
|
||||
|
||||
|
||||
+3
-13
@@ -1,6 +1,3 @@
|
||||
..
|
||||
Make sure to apply any changes to this file to README_RAW.rst as well!
|
||||
|
||||
.. image:: https://raw.githubusercontent.com/python-telegram-bot/logos/master/logo-text/png/ptb-logo-text_768.png
|
||||
:align: center
|
||||
:target: https://python-telegram-bot.org
|
||||
@@ -14,9 +11,9 @@
|
||||
:target: https://pypi.org/project/python-telegram-bot/
|
||||
:alt: Supported Python versions
|
||||
|
||||
.. image:: https://img.shields.io/badge/Bot%20API-7.1-blue?logo=telegram
|
||||
.. image:: https://img.shields.io/badge/Bot%20API-7.4-blue?logo=telegram
|
||||
:target: https://core.telegram.org/bots/api-changelog
|
||||
:alt: Supported Bot API versions
|
||||
:alt: Supported Bot API version
|
||||
|
||||
.. image:: https://img.shields.io/pypi/dm/python-telegram-bot
|
||||
:target: https://pypistats.org/packages/python-telegram-bot
|
||||
@@ -79,17 +76,10 @@ In addition to the pure API implementation, this library features a number of hi
|
||||
make the development of bots easy and straightforward. These classes are contained in the
|
||||
``telegram.ext`` submodule.
|
||||
|
||||
A pure API implementation *without* ``telegram.ext`` is available as the standalone package ``python-telegram-bot-raw``. `See here for details. <https://github.com/python-telegram-bot/python-telegram-bot/blob/master/README_RAW.rst>`_
|
||||
|
||||
Note
|
||||
----
|
||||
|
||||
Installing both ``python-telegram-bot`` and ``python-telegram-bot-raw`` in conjunction will result in undesired side-effects, so only install *one* of both.
|
||||
|
||||
Telegram API support
|
||||
====================
|
||||
|
||||
All types and methods of the Telegram Bot API **7.1** are supported.
|
||||
All types and methods of the Telegram Bot API **7.4** are supported.
|
||||
|
||||
Installing
|
||||
==========
|
||||
|
||||
+13
-6
@@ -1,6 +1,3 @@
|
||||
..
|
||||
Make sure to apply any changes to this file to README.rst as well!
|
||||
|
||||
.. image:: https://github.com/python-telegram-bot/logos/blob/master/logo-text/png/ptb-raw-logo-text_768.png?raw=true
|
||||
:align: center
|
||||
:target: https://python-telegram-bot.org
|
||||
@@ -14,9 +11,9 @@
|
||||
:target: https://pypi.org/project/python-telegram-bot-raw/
|
||||
:alt: Supported Python versions
|
||||
|
||||
.. image:: https://img.shields.io/badge/Bot%20API-7.1-blue?logo=telegram
|
||||
.. image:: https://img.shields.io/badge/Bot%20API-7.4-blue?logo=telegram
|
||||
:target: https://core.telegram.org/bots/api-changelog
|
||||
:alt: Supported Bot API versions
|
||||
:alt: Supported Bot API version
|
||||
|
||||
.. image:: https://img.shields.io/pypi/dm/python-telegram-bot-raw
|
||||
:target: https://pypistats.org/packages/python-telegram-bot-raw
|
||||
@@ -62,6 +59,16 @@
|
||||
:target: https://telegram.me/pythontelegrambotgroup
|
||||
:alt: Telegram Group
|
||||
|
||||
⚠️ Deprecation Notice
|
||||
=====================
|
||||
|
||||
The ``python-telegram-bot-raw`` library will no longer be updated after 21.3.
|
||||
Please instead use the ``python-telegram-bot`` `library <https://pypi.org/python-telegram-bot>`_.
|
||||
The change requires no changes in your code and requires no additional dependencies.
|
||||
For additional information, please see this `channel post <https://t.me/pythontelegrambotchannel/145>`_.
|
||||
|
||||
----
|
||||
|
||||
We have made you a wrapper you can't refuse
|
||||
|
||||
We have a vibrant community of developers helping each other in our `Telegram group <https://telegram.me/pythontelegrambotgroup>`_. Join us!
|
||||
@@ -85,7 +92,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 **7.1** are supported.
|
||||
All types and methods of the Telegram Bot API **7.4** are supported.
|
||||
|
||||
Installing
|
||||
==========
|
||||
|
||||
@@ -46,6 +46,7 @@ PRIVATE_BASE_CLASSES = {
|
||||
"_BaseThumbedMedium": "TelegramObject",
|
||||
"_BaseMedium": "TelegramObject",
|
||||
"_CredentialsBase": "TelegramObject",
|
||||
"_ChatBase": "TelegramObject",
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
sphinx==7.2.6
|
||||
furo==2024.1.29
|
||||
sphinx==7.3.7
|
||||
furo==2024.5.6
|
||||
furo-sphinx-search @ git+https://github.com/harshil21/furo-sphinx-search@v0.2.0.1
|
||||
sphinx-paramlinks==0.6.0
|
||||
sphinxcontrib-mermaid==0.9.2
|
||||
|
||||
+9
-9
@@ -20,9 +20,13 @@ author = "Leandro Toledo"
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = "21.0" # telegram.__version__[:3]
|
||||
|
||||
# Import needs to be below the sys.path.insert above
|
||||
import telegram # noqa: E402
|
||||
|
||||
version = telegram.__version__
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = "21.0" # telegram.__version__
|
||||
release = telegram.__version__
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
needs_sphinx = "6.1.3"
|
||||
@@ -67,7 +71,9 @@ source_suffix = ".rst"
|
||||
master_doc = "index"
|
||||
|
||||
# Global substitutions
|
||||
rst_prolog = (Path.cwd() / "../substitutions/global.rst").read_text(encoding="utf-8")
|
||||
rst_prolog = ""
|
||||
for file in Path.cwd().glob("../substitutions/*.rst"):
|
||||
rst_prolog += "\n" + file.read_text(encoding="utf-8")
|
||||
|
||||
# -- Extension settings ------------------------------------------------
|
||||
napoleon_use_admonition_for_examples = True
|
||||
@@ -140,12 +146,6 @@ 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>.'
|
||||
),
|
||||
"footer_icons": [
|
||||
{
|
||||
# Telegram channel logo
|
||||
|
||||
@@ -113,6 +113,10 @@
|
||||
:align: left
|
||||
:widths: 1 4
|
||||
|
||||
* - :meth:`~telegram.Bot.approve_chat_join_request`
|
||||
- Used for approving a chat join request
|
||||
* - :meth:`~telegram.Bot.decline_chat_join_request`
|
||||
- Used for declining a chat join request
|
||||
* - :meth:`~telegram.Bot.ban_chat_member`
|
||||
- Used for banning a member from the chat
|
||||
* - :meth:`~telegram.Bot.unban_chat_member`
|
||||
@@ -137,10 +141,6 @@
|
||||
- Used for editing a non-primary invite link
|
||||
* - :meth:`~telegram.Bot.revoke_chat_invite_link`
|
||||
- Used for revoking an invite link created by the bot
|
||||
* - :meth:`~telegram.Bot.approve_chat_join_request`
|
||||
- Used for approving a chat join request
|
||||
* - :meth:`~telegram.Bot.decline_chat_join_request`
|
||||
- Used for declining a chat join request
|
||||
* - :meth:`~telegram.Bot.set_chat_photo`
|
||||
- Used for setting a photo to a chat
|
||||
* - :meth:`~telegram.Bot.delete_chat_photo`
|
||||
@@ -155,6 +155,8 @@
|
||||
- Used for unpinning a message
|
||||
* - :meth:`~telegram.Bot.unpin_all_chat_messages`
|
||||
- Used for unpinning all pinned chat messages
|
||||
* - :meth:`~telegram.Bot.get_business_connection`
|
||||
- Used for getting information about the business account.
|
||||
* - :meth:`~telegram.Bot.get_user_profile_photos`
|
||||
- Used for obtaining user's profile pictures
|
||||
* - :meth:`~telegram.Bot.get_chat`
|
||||
@@ -237,6 +239,8 @@
|
||||
- Used for setting a sticker set of a chat
|
||||
* - :meth:`~telegram.Bot.delete_chat_sticker_set`
|
||||
- Used for deleting the set sticker set of a chat
|
||||
* - :meth:`~telegram.Bot.replace_sticker_in_set`
|
||||
- Used for replacing a sticker in a set
|
||||
* - :meth:`~telegram.Bot.set_sticker_position_in_set`
|
||||
- Used for moving a sticker's position in the set
|
||||
* - :meth:`~telegram.Bot.set_sticker_set_title`
|
||||
@@ -365,6 +369,8 @@
|
||||
- Used for getting basic info about a file
|
||||
* - :meth:`~telegram.Bot.get_me`
|
||||
- Used for getting basic information about the bot
|
||||
* - :meth:`~telegram.Bot.refund_star_payment`
|
||||
- Used for refunding a payment in Telegram Stars
|
||||
|
||||
.. raw:: html
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ Available Types
|
||||
|
||||
telegram.animation
|
||||
telegram.audio
|
||||
telegram.birthdate
|
||||
telegram.botcommand
|
||||
telegram.botcommandscope
|
||||
telegram.botcommandscopeallchatadministrators
|
||||
@@ -18,9 +19,25 @@ Available Types
|
||||
telegram.botdescription
|
||||
telegram.botname
|
||||
telegram.botshortdescription
|
||||
telegram.businessconnection
|
||||
telegram.businessintro
|
||||
telegram.businesslocation
|
||||
telegram.businessopeninghours
|
||||
telegram.businessopeninghoursinterval
|
||||
telegram.businessmessagesdeleted
|
||||
telegram.callbackquery
|
||||
telegram.chat
|
||||
telegram.chatadministratorrights
|
||||
telegram.chatbackground
|
||||
telegram.backgroundtype
|
||||
telegram.backgroundtypefill
|
||||
telegram.backgroundtypewallpaper
|
||||
telegram.backgroundtypepattern
|
||||
telegram.backgroundtypechattheme
|
||||
telegram.backgroundfill
|
||||
telegram.backgroundfillsolid
|
||||
telegram.backgroundfillgradient
|
||||
telegram.backgroundfillfreeformgradient
|
||||
telegram.chatboost
|
||||
telegram.chatboostadded
|
||||
telegram.chatboostremoved
|
||||
@@ -29,6 +46,7 @@ Available Types
|
||||
telegram.chatboostsourcegiveaway
|
||||
telegram.chatboostsourcepremium
|
||||
telegram.chatboostupdated
|
||||
telegram.chatfullinfo
|
||||
telegram.chatinvitelink
|
||||
telegram.chatjoinrequest
|
||||
telegram.chatlocation
|
||||
@@ -70,6 +88,7 @@ Available Types
|
||||
telegram.inputmediadocument
|
||||
telegram.inputmediaphoto
|
||||
telegram.inputmediavideo
|
||||
telegram.inputpolloption
|
||||
telegram.inputsticker
|
||||
telegram.keyboardbutton
|
||||
telegram.keyboardbuttonpolltype
|
||||
@@ -107,6 +126,7 @@ Available Types
|
||||
telegram.replykeyboardremove
|
||||
telegram.replyparameters
|
||||
telegram.sentwebappmessage
|
||||
telegram.shareduser
|
||||
telegram.story
|
||||
telegram.switchinlinequerychosenchat
|
||||
telegram.telegramobject
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
BackgroundFill
|
||||
==============
|
||||
|
||||
.. versionadded:: 21.2
|
||||
|
||||
.. autoclass:: telegram.BackgroundFill
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,8 @@
|
||||
BackgroundFillFreeformGradient
|
||||
==============================
|
||||
|
||||
.. versionadded:: 21.2
|
||||
|
||||
.. autoclass:: telegram.BackgroundFillFreeformGradient
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,8 @@
|
||||
BackgroundFillGradient
|
||||
======================
|
||||
|
||||
.. versionadded:: 21.2
|
||||
|
||||
.. autoclass:: telegram.BackgroundFillGradient
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,8 @@
|
||||
BackgroundFillSolid
|
||||
===================
|
||||
|
||||
.. versionadded:: 21.2
|
||||
|
||||
.. autoclass:: telegram.BackgroundFillSolid
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,8 @@
|
||||
BackgroundType
|
||||
==============
|
||||
|
||||
.. versionadded:: 21.2
|
||||
|
||||
.. autoclass:: telegram.BackgroundType
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,8 @@
|
||||
BackgroundTypeChatTheme
|
||||
=======================
|
||||
|
||||
.. versionadded:: 21.2
|
||||
|
||||
.. autoclass:: telegram.BackgroundTypeChatTheme
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,8 @@
|
||||
BackgroundTypeFill
|
||||
==================
|
||||
|
||||
.. versionadded:: 21.2
|
||||
|
||||
.. autoclass:: telegram.BackgroundTypeFill
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,8 @@
|
||||
BackgroundTypePattern
|
||||
=====================
|
||||
|
||||
.. versionadded:: 21.2
|
||||
|
||||
.. autoclass:: telegram.BackgroundTypePattern
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,8 @@
|
||||
BackgroundTypeWallpaper
|
||||
=======================
|
||||
|
||||
.. versionadded:: 21.2
|
||||
|
||||
.. autoclass:: telegram.BackgroundTypeWallpaper
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,7 @@
|
||||
Birthdate
|
||||
=========
|
||||
|
||||
.. autoclass:: telegram.Birthdate
|
||||
:members:
|
||||
:show-inheritance:
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
BusinessConnection
|
||||
==================
|
||||
|
||||
.. autoclass:: telegram.BusinessConnection
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,6 @@
|
||||
BusinessIntro
|
||||
==================
|
||||
|
||||
.. autoclass:: telegram.BusinessIntro
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,6 @@
|
||||
BusinessLocation
|
||||
==================
|
||||
|
||||
.. autoclass:: telegram.BusinessLocation
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,6 @@
|
||||
BusinessMessagesDeleted
|
||||
=======================
|
||||
|
||||
.. autoclass:: telegram.BusinessMessagesDeleted
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,6 @@
|
||||
BusinessOpeningHours
|
||||
====================
|
||||
|
||||
.. autoclass:: telegram.BusinessOpeningHours
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,6 @@
|
||||
BusinessOpeningHoursInterval
|
||||
============================
|
||||
|
||||
.. autoclass:: telegram.BusinessOpeningHoursInterval
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -1,6 +1,8 @@
|
||||
Chat
|
||||
====
|
||||
|
||||
.. Also lists methods of _ChatBase, but not the ones of TelegramObject
|
||||
.. autoclass:: telegram.Chat
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:inherited-members: TelegramObject
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
ChatBackground
|
||||
==============
|
||||
|
||||
.. versionadded:: 21.2
|
||||
|
||||
.. autoclass:: telegram.ChatBackground
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,8 @@
|
||||
ChatFullInfo
|
||||
============
|
||||
|
||||
.. Also lists methods of _ChatBase, but not the ones of TelegramObject
|
||||
.. autoclass:: telegram.ChatFullInfo
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:inherited-members: TelegramObject
|
||||
@@ -0,0 +1,6 @@
|
||||
BusinessConnectionHandler
|
||||
=========================
|
||||
|
||||
.. autoclass:: telegram.ext.BusinessConnectionHandler
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,6 @@
|
||||
BusinessMessagesDeletedHandler
|
||||
==============================
|
||||
|
||||
.. autoclass:: telegram.ext.BusinessMessagesDeletedHandler
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -5,6 +5,8 @@ Handlers
|
||||
:titlesonly:
|
||||
|
||||
telegram.ext.basehandler
|
||||
telegram.ext.businessconnectionhandler
|
||||
telegram.ext.businessmessagesdeletedhandler
|
||||
telegram.ext.callbackqueryhandler
|
||||
telegram.ext.chatboosthandler
|
||||
telegram.ext.chatjoinrequesthandler
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
InputPollOption
|
||||
===============
|
||||
|
||||
.. autoclass:: telegram.InputPollOption
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -1,6 +1,6 @@
|
||||
PhotoSize
|
||||
=========
|
||||
.. Also lists methods of _BaseThumbedMedium, but not the ones of TelegramObject
|
||||
.. Also lists methods of _BaseMedium, but not the ones of TelegramObject
|
||||
|
||||
.. autoclass:: telegram.PhotoSize
|
||||
:members:
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
SharedUser
|
||||
==========
|
||||
|
||||
.. autoclass:: telegram.SharedUser
|
||||
:members:
|
||||
:show-inheritance:
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
.. |app_run_shutdown| replace:: The app will shut down when :exc:`KeyboardInterrupt` or :exc:`SystemExit` is raised. This also works from within handlers, error handlers and jobs. However, using :meth:`~telegram.ext.Application.stop_running` will give a somewhat cleaner shutdown behavior than manually raising those exceptions. On unix, the app will also shut down on receiving the signals specified by
|
||||
@@ -79,3 +79,11 @@
|
||||
.. |do_quote| replace:: If set to :obj:`True`, the replied message is quoted. For a dict, it must be the output of :meth:`~telegram.Message.build_reply_arguments` to specify exact ``reply_parameters``. If ``reply_to_message_id`` or ``reply_parameters`` are passed, this parameter will be ignored. Default: :obj:`True` in group chats and :obj:`False` in private chats.
|
||||
|
||||
.. |non_optional_story_argument| replace:: As of this version, this argument is now required. In accordance with our `stability policy <https://docs.python-telegram-bot.org/en/stable/stability_policy.html>`__, the signature will be kept as optional for now, though they are mandatory and an error will be raised if you don't pass it.
|
||||
|
||||
.. |business_id_str| replace:: Unique identifier of the business connection on behalf of which the message will be sent.
|
||||
|
||||
.. |message_effect_id| replace:: Unique identifier of the message effect to be added to the message; for private chats only.
|
||||
|
||||
.. |show_cap_above_med| replace:: :obj:`True`, if the caption must be shown above the message media.
|
||||
|
||||
.. |tg_stars| replace:: `Telegram Stars <https://t.me/BotNews/90>`__
|
||||
|
||||
+6
-4
@@ -20,13 +20,15 @@ explicit-preview-rules = 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", "SLOT", "PERF", "PYI", "FLY", "AIR", "RUF022",
|
||||
"RUF023", "Q", "INP",]
|
||||
"RUF023", "Q", "INP", "W", "YTT", "DTZ", "ARG"]
|
||||
# Add "FURB" after it's out of preview
|
||||
# Add "A (flake8-builtins)" after we drop pylint
|
||||
|
||||
[tool.ruff.lint.per-file-ignores]
|
||||
"tests/*.py" = ["B018"]
|
||||
"tests/**.py" = ["RUF012", "ASYNC101"]
|
||||
"docs/**.py" = ["INP001"]
|
||||
"tests/**.py" = ["RUF012", "ASYNC101", "DTZ", "ARG"]
|
||||
"docs/**.py" = ["INP001", "ARG"]
|
||||
"examples/**.py" = ["ARG"]
|
||||
|
||||
# PYLINT:
|
||||
[tool.pylint."messages control"]
|
||||
@@ -48,7 +50,7 @@ exclude-protected = ["_unfrozen"]
|
||||
# PYTEST:
|
||||
[tool.pytest.ini_options]
|
||||
testpaths = ["tests"]
|
||||
addopts = "--no-success-flaky-report -rsxX"
|
||||
addopts = "--no-success-flaky-report -rX"
|
||||
filterwarnings = [
|
||||
"error",
|
||||
"ignore::DeprecationWarning",
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
pre-commit # needed for pre-commit hooks in the git commit command
|
||||
|
||||
# For the test suite
|
||||
pytest==7.4.4
|
||||
pytest-asyncio==0.21.1 # needed because pytest doesn't come with native support for coroutines as tests
|
||||
pytest-xdist==3.5.0 # xdist runs tests in parallel
|
||||
setuptools # required for test_meta
|
||||
pytest==8.2.1
|
||||
pytest-asyncio==0.21.2 # needed because pytest doesn't come with native support for coroutines as tests
|
||||
pytest-xdist==3.6.1 # xdist runs tests in parallel
|
||||
flaky # Used for flaky tests (flaky decorator)
|
||||
beautifulsoup4 # used in test_official for parsing tg docs
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ def get_packages_requirements(raw: bool = False) -> Tuple[List[str], List[str]]:
|
||||
"""Build the package & requirements list for this project"""
|
||||
reqs = get_requirements()
|
||||
|
||||
exclude = ["tests*"]
|
||||
exclude = ["tests*", "docs*"]
|
||||
if raw:
|
||||
exclude.append("telegram.ext*")
|
||||
|
||||
|
||||
+71
-2
@@ -22,6 +22,16 @@ __author__ = "devs@python-telegram-bot.org"
|
||||
__all__ = (
|
||||
"Animation",
|
||||
"Audio",
|
||||
"BackgroundFill",
|
||||
"BackgroundFillFreeformGradient",
|
||||
"BackgroundFillGradient",
|
||||
"BackgroundFillSolid",
|
||||
"BackgroundType",
|
||||
"BackgroundTypeChatTheme",
|
||||
"BackgroundTypeFill",
|
||||
"BackgroundTypePattern",
|
||||
"BackgroundTypeWallpaper",
|
||||
"Birthdate",
|
||||
"Bot",
|
||||
"BotCommand",
|
||||
"BotCommandScope",
|
||||
@@ -35,10 +45,17 @@ __all__ = (
|
||||
"BotDescription",
|
||||
"BotName",
|
||||
"BotShortDescription",
|
||||
"BusinessConnection",
|
||||
"BusinessIntro",
|
||||
"BusinessLocation",
|
||||
"BusinessMessagesDeleted",
|
||||
"BusinessOpeningHours",
|
||||
"BusinessOpeningHoursInterval",
|
||||
"CallbackGame",
|
||||
"CallbackQuery",
|
||||
"Chat",
|
||||
"ChatAdministratorRights",
|
||||
"ChatBackground",
|
||||
"ChatBoost",
|
||||
"ChatBoostAdded",
|
||||
"ChatBoostRemoved",
|
||||
@@ -47,6 +64,7 @@ __all__ = (
|
||||
"ChatBoostSourceGiveaway",
|
||||
"ChatBoostSourcePremium",
|
||||
"ChatBoostUpdated",
|
||||
"ChatFullInfo",
|
||||
"ChatInviteLink",
|
||||
"ChatJoinRequest",
|
||||
"ChatLocation",
|
||||
@@ -124,6 +142,7 @@ __all__ = (
|
||||
"InputMediaPhoto",
|
||||
"InputMediaVideo",
|
||||
"InputMessageContent",
|
||||
"InputPollOption",
|
||||
"InputSticker",
|
||||
"InputTextMessageContent",
|
||||
"InputVenueMessageContent",
|
||||
@@ -184,6 +203,7 @@ __all__ = (
|
||||
"SecureData",
|
||||
"SecureValue",
|
||||
"SentWebAppMessage",
|
||||
"SharedUser",
|
||||
"ShippingAddress",
|
||||
"ShippingOption",
|
||||
"ShippingQuery",
|
||||
@@ -222,8 +242,10 @@ __all__ = (
|
||||
"warnings",
|
||||
)
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from . import _version, constants, error, helpers, request, warnings
|
||||
from ._birthdate import Birthdate
|
||||
from ._bot import Bot
|
||||
from ._botcommand import BotCommand
|
||||
from ._botcommandscope import (
|
||||
@@ -238,9 +260,29 @@ from ._botcommandscope import (
|
||||
)
|
||||
from ._botdescription import BotDescription, BotShortDescription
|
||||
from ._botname import BotName
|
||||
from ._business import (
|
||||
BusinessConnection,
|
||||
BusinessIntro,
|
||||
BusinessLocation,
|
||||
BusinessMessagesDeleted,
|
||||
BusinessOpeningHours,
|
||||
BusinessOpeningHoursInterval,
|
||||
)
|
||||
from ._callbackquery import CallbackQuery
|
||||
from ._chat import Chat
|
||||
from ._chatadministratorrights import ChatAdministratorRights
|
||||
from ._chatbackground import (
|
||||
BackgroundFill,
|
||||
BackgroundFillFreeformGradient,
|
||||
BackgroundFillGradient,
|
||||
BackgroundFillSolid,
|
||||
BackgroundType,
|
||||
BackgroundTypeChatTheme,
|
||||
BackgroundTypeFill,
|
||||
BackgroundTypePattern,
|
||||
BackgroundTypeWallpaper,
|
||||
ChatBackground,
|
||||
)
|
||||
from ._chatboost import (
|
||||
ChatBoost,
|
||||
ChatBoostAdded,
|
||||
@@ -252,6 +294,7 @@ from ._chatboost import (
|
||||
ChatBoostUpdated,
|
||||
UserChatBoosts,
|
||||
)
|
||||
from ._chatfullinfo import ChatFullInfo
|
||||
from ._chatinvitelink import ChatInviteLink
|
||||
from ._chatjoinrequest import ChatJoinRequest
|
||||
from ._chatlocation import ChatLocation
|
||||
@@ -386,20 +429,21 @@ from ._payment.shippingaddress import ShippingAddress
|
||||
from ._payment.shippingoption import ShippingOption
|
||||
from ._payment.shippingquery import ShippingQuery
|
||||
from ._payment.successfulpayment import SuccessfulPayment
|
||||
from ._poll import Poll, PollAnswer, PollOption
|
||||
from ._poll import InputPollOption, Poll, PollAnswer, PollOption
|
||||
from ._proximityalerttriggered import ProximityAlertTriggered
|
||||
from ._reaction import ReactionCount, ReactionType, ReactionTypeCustomEmoji, ReactionTypeEmoji
|
||||
from ._reply import ExternalReplyInfo, ReplyParameters, TextQuote
|
||||
from ._replykeyboardmarkup import ReplyKeyboardMarkup
|
||||
from ._replykeyboardremove import ReplyKeyboardRemove
|
||||
from ._sentwebappmessage import SentWebAppMessage
|
||||
from ._shared import ChatShared, UsersShared
|
||||
from ._shared import ChatShared, SharedUser, UsersShared
|
||||
from ._story import Story
|
||||
from ._switchinlinequerychosenchat import SwitchInlineQueryChosenChat
|
||||
from ._telegramobject import TelegramObject
|
||||
from ._update import Update
|
||||
from ._user import User
|
||||
from ._userprofilephotos import UserProfilePhotos
|
||||
from ._utils.warnings import warn
|
||||
from ._videochat import (
|
||||
VideoChatEnded,
|
||||
VideoChatParticipantsInvited,
|
||||
@@ -433,3 +477,28 @@ __bot_api_version__: str = _version.__bot_api_version__
|
||||
#:
|
||||
#: .. versionadded:: 20.0
|
||||
__bot_api_version_info__: constants._BotAPIVersion = _version.__bot_api_version_info__
|
||||
|
||||
|
||||
if not (Path(__file__).parent.resolve().absolute() / "ext").exists():
|
||||
_MESSAGE = (
|
||||
"Hey. You seem to be using the `python-telegram-bot-raw` library. "
|
||||
"Please note that this libray has been deprecated and will no longer be updated. "
|
||||
"Please instead use the `python-telegram-bot` library. The change requires no "
|
||||
"changes in your code and requires no additional dependencies. For additional "
|
||||
"information, please see the channel post at "
|
||||
"https://t.me/pythontelegrambotchannel/145."
|
||||
)
|
||||
|
||||
# DeprecationWarning is ignored by default in Python 3.7 and later by default outside
|
||||
# __main__ modules. We use both warning categories to increase the chance of the user
|
||||
# seeing the warning.
|
||||
|
||||
warn(
|
||||
warnings.PTBDeprecationWarning(version="21.3", message=_MESSAGE),
|
||||
stacklevel=2,
|
||||
)
|
||||
warn(
|
||||
message=_MESSAGE,
|
||||
category=warnings.PTBUserWarning,
|
||||
stacklevel=2,
|
||||
)
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2024
|
||||
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram Birthday."""
|
||||
from datetime import date
|
||||
from typing import Optional
|
||||
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._utils.types import JSONDict
|
||||
|
||||
|
||||
class Birthdate(TelegramObject):
|
||||
"""
|
||||
This object describes the birthdate of a user.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`day`, and :attr:`month` are equal.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
|
||||
Args:
|
||||
day (:obj:`int`): Day of the user's birth; 1-31.
|
||||
month (:obj:`int`): Month of the user's birth; 1-12.
|
||||
year (:obj:`int`, optional): Year of the user's birth.
|
||||
|
||||
Attributes:
|
||||
day (:obj:`int`): Day of the user's birth; 1-31.
|
||||
month (:obj:`int`): Month of the user's birth; 1-12.
|
||||
year (:obj:`int`): Optional. Year of the user's birth.
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = ("day", "month", "year")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
day: int,
|
||||
month: int,
|
||||
year: Optional[int] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
|
||||
# Required
|
||||
self.day: int = day
|
||||
self.month: int = month
|
||||
# Optional
|
||||
self.year: Optional[int] = year
|
||||
|
||||
self._id_attrs = (
|
||||
self.day,
|
||||
self.month,
|
||||
)
|
||||
|
||||
self._freeze()
|
||||
|
||||
def to_date(self, year: Optional[int] = None) -> date:
|
||||
"""Return the birthdate as a date object.
|
||||
|
||||
.. versionchanged:: 21.2
|
||||
Now returns a :obj:`datetime.date` object instead of a :obj:`datetime.datetime` object,
|
||||
as was originally intended.
|
||||
|
||||
Args:
|
||||
year (:obj:`int`, optional): The year to use. Required, if the :attr:`year` was not
|
||||
present.
|
||||
|
||||
Returns:
|
||||
:obj:`datetime.date`: The birthdate as a date object.
|
||||
"""
|
||||
if self.year is None and year is None:
|
||||
raise ValueError(
|
||||
"The `year` argument is required if the `year` attribute was not present."
|
||||
)
|
||||
|
||||
return date(year or self.year, self.month, self.day) # type: ignore[arg-type]
|
||||
+490
-208
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,445 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=redefined-builtin
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2024
|
||||
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/]
|
||||
"""This module contains the Telegram Business related classes."""
|
||||
|
||||
from datetime import datetime
|
||||
from typing import TYPE_CHECKING, Optional, Sequence, Tuple
|
||||
|
||||
from telegram._chat import Chat
|
||||
from telegram._files.location import Location
|
||||
from telegram._files.sticker import Sticker
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._user import User
|
||||
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||
from telegram._utils.datetime import extract_tzinfo_from_defaults, from_timestamp
|
||||
from telegram._utils.types import JSONDict
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import Bot
|
||||
|
||||
|
||||
class BusinessConnection(TelegramObject):
|
||||
"""
|
||||
Describes the connection of the bot with a business account.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal if their :attr:`id`, :attr:`user`, :attr:`user_chat_id`, :attr:`date`,
|
||||
:attr:`can_reply`, and :attr:`is_enabled` are equal.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
|
||||
Args:
|
||||
id (:obj:`str`): Unique identifier of the business connection.
|
||||
user (:class:`telegram.User`): Business account user that created the business connection.
|
||||
user_chat_id (:obj:`int`): Identifier of a private chat with the user who created the
|
||||
business connection.
|
||||
date (:obj:`datetime.datetime`): Date the connection was established in Unix time.
|
||||
can_reply (:obj:`bool`): True, if the bot can act on behalf of the business account in
|
||||
chats that were active in the last 24 hours.
|
||||
is_enabled (:obj:`bool`): True, if the connection is active.
|
||||
|
||||
Attributes:
|
||||
id (:obj:`str`): Unique identifier of the business connection.
|
||||
user (:class:`telegram.User`): Business account user that created the business connection.
|
||||
user_chat_id (:obj:`int`): Identifier of a private chat with the user who created the
|
||||
business connection.
|
||||
date (:obj:`datetime.datetime`): Date the connection was established in Unix time.
|
||||
can_reply (:obj:`bool`): True, if the bot can act on behalf of the business account in
|
||||
chats that were active in the last 24 hours.
|
||||
is_enabled (:obj:`bool`): True, if the connection is active.
|
||||
"""
|
||||
|
||||
__slots__ = (
|
||||
"can_reply",
|
||||
"date",
|
||||
"id",
|
||||
"is_enabled",
|
||||
"user",
|
||||
"user_chat_id",
|
||||
)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
id: str,
|
||||
user: "User",
|
||||
user_chat_id: int,
|
||||
date: datetime,
|
||||
can_reply: bool,
|
||||
is_enabled: bool,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
self.id: str = id
|
||||
self.user: User = user
|
||||
self.user_chat_id: int = user_chat_id
|
||||
self.date: datetime = date
|
||||
self.can_reply: bool = can_reply
|
||||
self.is_enabled: bool = is_enabled
|
||||
|
||||
self._id_attrs = (
|
||||
self.id,
|
||||
self.user,
|
||||
self.user_chat_id,
|
||||
self.date,
|
||||
self.can_reply,
|
||||
self.is_enabled,
|
||||
)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["BusinessConnection"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
if not data:
|
||||
return None
|
||||
|
||||
# Get the local timezone from the bot if it has defaults
|
||||
loc_tzinfo = extract_tzinfo_from_defaults(bot)
|
||||
|
||||
data["date"] = from_timestamp(data.get("date"), tzinfo=loc_tzinfo)
|
||||
data["user"] = User.de_json(data.get("user"), bot)
|
||||
|
||||
return super().de_json(data=data, bot=bot)
|
||||
|
||||
|
||||
class BusinessMessagesDeleted(TelegramObject):
|
||||
"""
|
||||
This object is received when messages are deleted from a connected business account.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal if their :attr:`business_connection_id`, :attr:`message_ids`, and
|
||||
:attr:`chat` are equal.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
|
||||
Args:
|
||||
business_connection_id (:obj:`str`): Unique identifier of the business connection.
|
||||
chat (:class:`telegram.Chat`): Information about a chat in the business account. The bot
|
||||
may not have access to the chat or the corresponding user.
|
||||
message_ids (Sequence[:obj:`int`]): A list of identifiers of the deleted messages in the
|
||||
chat of the business account.
|
||||
|
||||
Attributes:
|
||||
business_connection_id (:obj:`str`): Unique identifier of the business connection.
|
||||
chat (:class:`telegram.Chat`): Information about a chat in the business account. The bot
|
||||
may not have access to the chat or the corresponding user.
|
||||
message_ids (Tuple[:obj:`int`]): A list of identifiers of the deleted messages in the
|
||||
chat of the business account.
|
||||
"""
|
||||
|
||||
__slots__ = (
|
||||
"business_connection_id",
|
||||
"chat",
|
||||
"message_ids",
|
||||
)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
business_connection_id: str,
|
||||
chat: Chat,
|
||||
message_ids: Sequence[int],
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
self.business_connection_id: str = business_connection_id
|
||||
self.chat: Chat = chat
|
||||
self.message_ids: Tuple[int, ...] = parse_sequence_arg(message_ids)
|
||||
|
||||
self._id_attrs = (
|
||||
self.business_connection_id,
|
||||
self.chat,
|
||||
self.message_ids,
|
||||
)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["BusinessMessagesDeleted"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data["chat"] = Chat.de_json(data.get("chat"), bot)
|
||||
|
||||
return super().de_json(data=data, bot=bot)
|
||||
|
||||
|
||||
class BusinessIntro(TelegramObject):
|
||||
"""
|
||||
This object contains information about the start page settings of a Telegram Business account.
|
||||
|
||||
Objects of this class are comparable in terms of equality.
|
||||
Two objects of this class are considered equal, if their
|
||||
:attr:`title`, :attr:`message` and :attr:`sticker` are equal.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
|
||||
Args:
|
||||
title (:obj:`str`, optional): Title text of the business intro.
|
||||
message (:obj:`str`, optional): Message text of the business intro.
|
||||
sticker (:class:`telegram.Sticker`, optional): Sticker of the business intro.
|
||||
|
||||
Attributes:
|
||||
title (:obj:`str`): Optional. Title text of the business intro.
|
||||
message (:obj:`str`): Optional. Message text of the business intro.
|
||||
sticker (:class:`telegram.Sticker`): Optional. Sticker of the business intro.
|
||||
"""
|
||||
|
||||
__slots__ = (
|
||||
"message",
|
||||
"sticker",
|
||||
"title",
|
||||
)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
title: Optional[str] = None,
|
||||
message: Optional[str] = None,
|
||||
sticker: Optional[Sticker] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
self.title: Optional[str] = title
|
||||
self.message: Optional[str] = message
|
||||
self.sticker: Optional[Sticker] = sticker
|
||||
|
||||
self._id_attrs = (self.title, self.message, self.sticker)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["BusinessIntro"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data["sticker"] = Sticker.de_json(data.get("sticker"), bot)
|
||||
|
||||
return super().de_json(data=data, bot=bot)
|
||||
|
||||
|
||||
class BusinessLocation(TelegramObject):
|
||||
"""
|
||||
This object contains information about the location of a Telegram Business account.
|
||||
|
||||
Objects of this class are comparable in terms of equality.
|
||||
Two objects of this class are considered equal, if their
|
||||
:attr:`address` is equal.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
|
||||
Args:
|
||||
address (:obj:`str`): Address of the business.
|
||||
location (:class:`telegram.Location`, optional): Location of the business.
|
||||
|
||||
Attributes:
|
||||
address (:obj:`str`): Address of the business.
|
||||
location (:class:`telegram.Location`): Optional. Location of the business.
|
||||
"""
|
||||
|
||||
__slots__ = (
|
||||
"address",
|
||||
"location",
|
||||
)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
address: str,
|
||||
location: Optional[Location] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
self.address: str = address
|
||||
self.location: Optional[Location] = location
|
||||
|
||||
self._id_attrs = (self.address,)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["BusinessLocation"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data["location"] = Location.de_json(data.get("location"), bot)
|
||||
|
||||
return super().de_json(data=data, bot=bot)
|
||||
|
||||
|
||||
class BusinessOpeningHoursInterval(TelegramObject):
|
||||
"""
|
||||
This object describes an interval of time during which a business is open.
|
||||
|
||||
Objects of this class are comparable in terms of equality.
|
||||
Two objects of this class are considered equal, if their
|
||||
:attr:`opening_minute` and :attr:`closing_minute` are equal.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
|
||||
Examples:
|
||||
A day has (24 * 60 =) 1440 minutes, a week has (7 * 1440 =) 10080 minutes.
|
||||
Starting the the minute's sequence from Monday, example values of
|
||||
:attr:`opening_minute`, :attr:`closing_minute` will map to the following day times:
|
||||
|
||||
* Monday - 8am to 8:30pm:
|
||||
- ``opening_minute = 480`` :guilabel:`8 * 60`
|
||||
- ``closing_minute = 1230`` :guilabel:`20 * 60 + 30`
|
||||
* Tuesday - 24 hours:
|
||||
- ``opening_minute = 1440`` :guilabel:`24 * 60`
|
||||
- ``closing_minute = 2879`` :guilabel:`2 * 24 * 60 - 1`
|
||||
* Sunday - 12am - 11:58pm:
|
||||
- ``opening_minute = 8640`` :guilabel:`6 * 24 * 60`
|
||||
- ``closing_minute = 10078`` :guilabel:`7 * 24 * 60 - 2`
|
||||
|
||||
Args:
|
||||
opening_minute (:obj:`int`): The minute's sequence number in a week, starting on Monday,
|
||||
marking the start of the time interval during which the business is open;
|
||||
0 - 7 * 24 * 60.
|
||||
closing_minute (:obj:`int`): The minute's
|
||||
sequence number in a week, starting on Monday, marking the end of the time interval
|
||||
during which the business is open; 0 - 8 * 24 * 60
|
||||
|
||||
Attributes:
|
||||
opening_minute (:obj:`int`): The minute's sequence number in a week, starting on Monday,
|
||||
marking the start of the time interval during which the business is open;
|
||||
0 - 7 * 24 * 60.
|
||||
closing_minute (:obj:`int`): The minute's
|
||||
sequence number in a week, starting on Monday, marking the end of the time interval
|
||||
during which the business is open; 0 - 8 * 24 * 60
|
||||
"""
|
||||
|
||||
__slots__ = ("_closing_time", "_opening_time", "closing_minute", "opening_minute")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
opening_minute: int,
|
||||
closing_minute: int,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
self.opening_minute: int = opening_minute
|
||||
self.closing_minute: int = closing_minute
|
||||
|
||||
self._opening_time: Optional[Tuple[int, int, int]] = None
|
||||
self._closing_time: Optional[Tuple[int, int, int]] = None
|
||||
|
||||
self._id_attrs = (self.opening_minute, self.closing_minute)
|
||||
|
||||
self._freeze()
|
||||
|
||||
def _parse_minute(self, minute: int) -> Tuple[int, int, int]:
|
||||
return (minute // 1440, minute % 1440 // 60, minute % 1440 % 60)
|
||||
|
||||
@property
|
||||
def opening_time(self) -> Tuple[int, int, int]:
|
||||
"""Convenience attribute. A :obj:`tuple` parsed from :attr:`opening_minute`. It contains
|
||||
the `weekday`, `hour` and `minute` in the same ranges as :attr:`datetime.datetime.weekday`,
|
||||
:attr:`datetime.datetime.hour` and :attr:`datetime.datetime.minute`
|
||||
|
||||
Returns:
|
||||
Tuple[:obj:`int`, :obj:`int`, :obj:`int`]:
|
||||
"""
|
||||
if self._opening_time is None:
|
||||
self._opening_time = self._parse_minute(self.opening_minute)
|
||||
return self._opening_time
|
||||
|
||||
@property
|
||||
def closing_time(self) -> Tuple[int, int, int]:
|
||||
"""Convenience attribute. A :obj:`tuple` parsed from :attr:`closing_minute`. It contains
|
||||
the `weekday`, `hour` and `minute` in the same ranges as :attr:`datetime.datetime.weekday`,
|
||||
:attr:`datetime.datetime.hour` and :attr:`datetime.datetime.minute`
|
||||
|
||||
Returns:
|
||||
Tuple[:obj:`int`, :obj:`int`, :obj:`int`]:
|
||||
"""
|
||||
if self._closing_time is None:
|
||||
self._closing_time = self._parse_minute(self.closing_minute)
|
||||
return self._closing_time
|
||||
|
||||
|
||||
class BusinessOpeningHours(TelegramObject):
|
||||
"""
|
||||
This object describes the opening hours of a business.
|
||||
|
||||
Objects of this class are comparable in terms of equality.
|
||||
Two objects of this class are considered equal, if their
|
||||
:attr:`time_zone_name` and :attr:`opening_hours` are equal.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
|
||||
Args:
|
||||
time_zone_name (:obj:`str`): Unique name of the time zone for which the opening
|
||||
hours are defined.
|
||||
opening_hours (Sequence[:class:`telegram.BusinessOpeningHoursInterval`]): List of
|
||||
time intervals describing business opening hours.
|
||||
|
||||
Attributes:
|
||||
time_zone_name (:obj:`str`): Unique name of the time zone for which the opening
|
||||
hours are defined.
|
||||
opening_hours (Sequence[:class:`telegram.BusinessOpeningHoursInterval`]): List of
|
||||
time intervals describing business opening hours.
|
||||
"""
|
||||
|
||||
__slots__ = ("opening_hours", "time_zone_name")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
time_zone_name: str,
|
||||
opening_hours: Sequence[BusinessOpeningHoursInterval],
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
self.time_zone_name: str = time_zone_name
|
||||
self.opening_hours: Sequence[BusinessOpeningHoursInterval] = parse_sequence_arg(
|
||||
opening_hours
|
||||
)
|
||||
|
||||
self._id_attrs = (self.time_zone_name, self.opening_hours)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["BusinessOpeningHours"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data["opening_hours"] = BusinessOpeningHoursInterval.de_list(
|
||||
data.get("opening_hours"), bot
|
||||
)
|
||||
|
||||
return super().de_json(data=data, bot=bot)
|
||||
@@ -281,6 +281,7 @@ class CallbackQuery(TelegramObject):
|
||||
reply_markup: Optional["InlineKeyboardMarkup"] = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Optional[Sequence["MessageEntity"]] = None,
|
||||
show_caption_above_media: Optional[bool] = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
@@ -326,6 +327,7 @@ class CallbackQuery(TelegramObject):
|
||||
caption_entities=caption_entities,
|
||||
chat_id=None,
|
||||
message_id=None,
|
||||
show_caption_above_media=show_caption_above_media,
|
||||
)
|
||||
return await self._get_message().edit_caption(
|
||||
caption=caption,
|
||||
@@ -337,6 +339,7 @@ class CallbackQuery(TelegramObject):
|
||||
parse_mode=parse_mode,
|
||||
api_kwargs=api_kwargs,
|
||||
caption_entities=caption_entities,
|
||||
show_caption_above_media=show_caption_above_media,
|
||||
)
|
||||
|
||||
async def edit_message_reply_markup(
|
||||
@@ -461,6 +464,7 @@ class CallbackQuery(TelegramObject):
|
||||
horizontal_accuracy: Optional[float] = None,
|
||||
heading: Optional[int] = None,
|
||||
proximity_alert_radius: Optional[int] = None,
|
||||
live_period: Optional[int] = None,
|
||||
*,
|
||||
location: Optional[Location] = None,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
@@ -509,6 +513,7 @@ class CallbackQuery(TelegramObject):
|
||||
horizontal_accuracy=horizontal_accuracy,
|
||||
heading=heading,
|
||||
proximity_alert_radius=proximity_alert_radius,
|
||||
live_period=live_period,
|
||||
chat_id=None,
|
||||
message_id=None,
|
||||
)
|
||||
@@ -525,6 +530,7 @@ class CallbackQuery(TelegramObject):
|
||||
horizontal_accuracy=horizontal_accuracy,
|
||||
heading=heading,
|
||||
proximity_alert_radius=proximity_alert_radius,
|
||||
live_period=live_period,
|
||||
)
|
||||
|
||||
async def stop_message_live_location(
|
||||
@@ -812,6 +818,7 @@ class CallbackQuery(TelegramObject):
|
||||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
message_thread_id: Optional[int] = None,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
show_caption_above_media: Optional[bool] = None,
|
||||
*,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
@@ -858,6 +865,7 @@ class CallbackQuery(TelegramObject):
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
reply_parameters=reply_parameters,
|
||||
show_caption_above_media=show_caption_above_media,
|
||||
)
|
||||
|
||||
MAX_ANSWER_TEXT_LENGTH: Final[int] = (
|
||||
|
||||
+196
-497
File diff suppressed because it is too large
Load Diff
@@ -44,6 +44,11 @@ class ChatAdministratorRights(TelegramObject):
|
||||
: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.
|
||||
|
||||
.. versionchanged:: 21.1
|
||||
As of this version, :attr:`can_post_stories`, :attr:`can_edit_stories`,
|
||||
and :attr:`can_delete_stories` is now required. Thus, the order of arguments had to be
|
||||
changed.
|
||||
|
||||
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
|
||||
@@ -75,8 +80,9 @@ class ChatAdministratorRights(TelegramObject):
|
||||
.. versionadded:: 20.6
|
||||
.. versionchanged:: 21.0
|
||||
|non_optional_story_argument|
|
||||
can_edit_stories (:obj:`bool`): :obj:`True`, if the administrator can edit
|
||||
stories posted by other users.
|
||||
can_edit_stories (:obj:`bool`): :obj:`True`, if the administrator can edit stories posted
|
||||
by other users, post stories to the chat page, pin chat stories, and access the chat's
|
||||
story archive
|
||||
|
||||
.. versionadded:: 20.6
|
||||
.. versionchanged:: 21.0
|
||||
@@ -123,8 +129,9 @@ class ChatAdministratorRights(TelegramObject):
|
||||
.. versionadded:: 20.6
|
||||
.. versionchanged:: 21.0
|
||||
|non_optional_story_argument|
|
||||
can_edit_stories (:obj:`bool`): :obj:`True`, if the administrator can edit
|
||||
stories posted by other users.
|
||||
can_edit_stories (:obj:`bool`): :obj:`True`, if the administrator can edit stories posted
|
||||
by other users, post stories to the chat page, pin chat stories, and access the chat's
|
||||
story archive
|
||||
|
||||
.. versionadded:: 20.6
|
||||
.. versionchanged:: 21.0
|
||||
@@ -169,13 +176,13 @@ class ChatAdministratorRights(TelegramObject):
|
||||
can_promote_members: bool,
|
||||
can_change_info: bool,
|
||||
can_invite_users: bool,
|
||||
can_post_stories: bool,
|
||||
can_edit_stories: bool,
|
||||
can_delete_stories: bool,
|
||||
can_post_messages: Optional[bool] = None,
|
||||
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:
|
||||
@@ -189,12 +196,6 @@ class ChatAdministratorRights(TelegramObject):
|
||||
self.can_promote_members: bool = can_promote_members
|
||||
self.can_change_info: bool = can_change_info
|
||||
self.can_invite_users: bool = can_invite_users
|
||||
# Not actually optionals but because of backwards compatability we pretend they are
|
||||
if can_post_stories is None or can_edit_stories is None or can_delete_stories is None:
|
||||
raise TypeError(
|
||||
"As of v21.0 can_post_stories, can_edit_stories and can_delete_stories"
|
||||
" must be set in order to create this object."
|
||||
)
|
||||
self.can_post_stories: bool = can_post_stories
|
||||
self.can_edit_stories: bool = can_edit_stories
|
||||
self.can_delete_stories: bool = can_delete_stories
|
||||
|
||||
@@ -0,0 +1,540 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2024
|
||||
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains objects related to chat backgrounds."""
|
||||
from typing import TYPE_CHECKING, Dict, Final, Optional, Sequence, Tuple, Type
|
||||
|
||||
from telegram import constants
|
||||
from telegram._files.document import Document
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._utils import enum
|
||||
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||
from telegram._utils.types import JSONDict
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import Bot
|
||||
|
||||
|
||||
class BackgroundFill(TelegramObject):
|
||||
"""Base class for Telegram BackgroundFill Objects. It can be one of:
|
||||
|
||||
* :class:`telegram.BackgroundFillSolid`
|
||||
* :class:`telegram.BackgroundFillGradient`
|
||||
* :class:`telegram.BackgroundFillFreeformGradient`
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`type` is equal.
|
||||
|
||||
.. versionadded:: 21.2
|
||||
|
||||
Args:
|
||||
type (:obj:`str`): Type of the background fill. Can be one of:
|
||||
:attr:`~telegram.BackgroundFill.SOLID`, :attr:`~telegram.BackgroundFill.GRADIENT`
|
||||
or :attr:`~telegram.BackgroundFill.FREEFORM_GRADIENT`.
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): Type of the background fill. Can be one of:
|
||||
:attr:`~telegram.BackgroundFill.SOLID`, :attr:`~telegram.BackgroundFill.GRADIENT`
|
||||
or :attr:`~telegram.BackgroundFill.FREEFORM_GRADIENT`.
|
||||
"""
|
||||
|
||||
__slots__ = ("type",)
|
||||
|
||||
SOLID: Final[constants.BackgroundFillType] = constants.BackgroundFillType.SOLID
|
||||
""":const:`telegram.constants.BackgroundFillType.SOLID`"""
|
||||
GRADIENT: Final[constants.BackgroundFillType] = constants.BackgroundFillType.GRADIENT
|
||||
""":const:`telegram.constants.BackgroundFillType.GRADIENT`"""
|
||||
FREEFORM_GRADIENT: Final[constants.BackgroundFillType] = (
|
||||
constants.BackgroundFillType.FREEFORM_GRADIENT
|
||||
)
|
||||
""":const:`telegram.constants.BackgroundFillType.FREEFORM_GRADIENT`"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
type: str, # pylint: disable=redefined-builtin
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
# Required by all subclasses
|
||||
self.type: str = enum.get_member(constants.BackgroundFillType, type, type)
|
||||
|
||||
self._id_attrs = (self.type,)
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["BackgroundFill"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
if not data:
|
||||
return None
|
||||
|
||||
_class_mapping: Dict[str, Type[BackgroundFill]] = {
|
||||
cls.SOLID: BackgroundFillSolid,
|
||||
cls.GRADIENT: BackgroundFillGradient,
|
||||
cls.FREEFORM_GRADIENT: BackgroundFillFreeformGradient,
|
||||
}
|
||||
|
||||
if cls is BackgroundFill and data.get("type") in _class_mapping:
|
||||
return _class_mapping[data.pop("type")].de_json(data=data, bot=bot)
|
||||
|
||||
return super().de_json(data=data, bot=bot)
|
||||
|
||||
|
||||
class BackgroundFillSolid(BackgroundFill):
|
||||
"""
|
||||
The background is filled using the selected color.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`color` is equal.
|
||||
|
||||
.. versionadded:: 21.2
|
||||
|
||||
Args:
|
||||
color (:obj:`int`): The color of the background fill in the `RGB24` format.
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): Type of the background fill. Always
|
||||
:attr:`~telegram.BackgroundFill.SOLID`.
|
||||
color (:obj:`int`): The color of the background fill in the `RGB24` format.
|
||||
"""
|
||||
|
||||
__slots__ = ("color",)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
color: int,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(type=self.SOLID, api_kwargs=api_kwargs)
|
||||
|
||||
with self._unfrozen():
|
||||
self.color: int = color
|
||||
|
||||
self._id_attrs = (self.color,)
|
||||
|
||||
|
||||
class BackgroundFillGradient(BackgroundFill):
|
||||
"""
|
||||
The background is a gradient fill.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`top_color`, :attr:`bottom_color`
|
||||
and :attr:`rotation_angle` are equal.
|
||||
|
||||
.. versionadded:: 21.2
|
||||
|
||||
Args:
|
||||
top_color (:obj:`int`): Top color of the gradient in the `RGB24` format.
|
||||
bottom_color (:obj:`int`): Bottom color of the gradient in the `RGB24` format.
|
||||
rotation_angle (:obj:`int`): Clockwise rotation angle of the background
|
||||
fill in degrees;
|
||||
0-:tg-const:`telegram.constants.BackgroundFillLimit.MAX_ROTATION_ANGLE`.
|
||||
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): Type of the background fill. Always
|
||||
:attr:`~telegram.BackgroundFill.GRADIENT`.
|
||||
top_color (:obj:`int`): Top color of the gradient in the `RGB24` format.
|
||||
bottom_color (:obj:`int`): Bottom color of the gradient in the `RGB24` format.
|
||||
rotation_angle (:obj:`int`): Clockwise rotation angle of the background
|
||||
fill in degrees;
|
||||
0-:tg-const:`telegram.constants.BackgroundFillLimit.MAX_ROTATION_ANGLE`.
|
||||
"""
|
||||
|
||||
__slots__ = ("bottom_color", "rotation_angle", "top_color")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
top_color: int,
|
||||
bottom_color: int,
|
||||
rotation_angle: int,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(type=self.GRADIENT, api_kwargs=api_kwargs)
|
||||
|
||||
with self._unfrozen():
|
||||
self.top_color: int = top_color
|
||||
self.bottom_color: int = bottom_color
|
||||
self.rotation_angle: int = rotation_angle
|
||||
|
||||
self._id_attrs = (self.top_color, self.bottom_color, self.rotation_angle)
|
||||
|
||||
|
||||
class BackgroundFillFreeformGradient(BackgroundFill):
|
||||
"""
|
||||
The background is a freeform gradient that rotates after every message in the chat.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`colors` is equal.
|
||||
|
||||
.. versionadded:: 21.2
|
||||
|
||||
Args:
|
||||
colors (Sequence[:obj:`int`]): A list of the 3 or 4 base colors that are used to
|
||||
generate the freeform gradient in the `RGB24` format
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): Type of the background fill. Always
|
||||
:attr:`~telegram.BackgroundFill.FREEFORM_GRADIENT`.
|
||||
colors (Sequence[:obj:`int`]): A list of the 3 or 4 base colors that are used to
|
||||
generate the freeform gradient in the `RGB24` format
|
||||
"""
|
||||
|
||||
__slots__ = ("colors",)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
colors: Sequence[int],
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(type=self.FREEFORM_GRADIENT, api_kwargs=api_kwargs)
|
||||
|
||||
with self._unfrozen():
|
||||
self.colors: Tuple[int, ...] = parse_sequence_arg(colors)
|
||||
|
||||
self._id_attrs = (self.colors,)
|
||||
|
||||
|
||||
class BackgroundType(TelegramObject):
|
||||
"""Base class for Telegram BackgroundType Objects. It can be one of:
|
||||
|
||||
* :class:`telegram.BackgroundTypeFill`
|
||||
* :class:`telegram.BackgroundTypeWallpaper`
|
||||
* :class:`telegram.BackgroundTypePattern`
|
||||
* :class:`telegram.BackgroundTypeChatTheme`.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`type` is equal.
|
||||
|
||||
.. versionadded:: 21.2
|
||||
|
||||
Args:
|
||||
type (:obj:`str`): Type of the background. Can be one of:
|
||||
:attr:`~telegram.BackgroundType.FILL`, :attr:`~telegram.BackgroundType.WALLPAPER`
|
||||
:attr:`~telegram.BackgroundType.PATTERN` or
|
||||
:attr:`~telegram.BackgroundType.CHAT_THEME`.
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): Type of the background. Can be one of:
|
||||
:attr:`~telegram.BackgroundType.FILL`, :attr:`~telegram.BackgroundType.WALLPAPER`
|
||||
:attr:`~telegram.BackgroundType.PATTERN` or
|
||||
:attr:`~telegram.BackgroundType.CHAT_THEME`.
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = ("type",)
|
||||
|
||||
FILL: Final[constants.BackgroundTypeType] = constants.BackgroundTypeType.FILL
|
||||
""":const:`telegram.constants.BackgroundTypeType.FILL`"""
|
||||
WALLPAPER: Final[constants.BackgroundTypeType] = constants.BackgroundTypeType.WALLPAPER
|
||||
""":const:`telegram.constants.BackgroundTypeType.WALLPAPER`"""
|
||||
PATTERN: Final[constants.BackgroundTypeType] = constants.BackgroundTypeType.PATTERN
|
||||
""":const:`telegram.constants.BackgroundTypeType.PATTERN`"""
|
||||
CHAT_THEME: Final[constants.BackgroundTypeType] = constants.BackgroundTypeType.CHAT_THEME
|
||||
""":const:`telegram.constants.BackgroundTypeType.CHAT_THEME`"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
type: str, # pylint: disable=redefined-builtin
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
# Required by all subclasses
|
||||
self.type: str = enum.get_member(constants.BackgroundTypeType, type, type)
|
||||
|
||||
self._id_attrs = (self.type,)
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["BackgroundType"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
if not data:
|
||||
return None
|
||||
|
||||
_class_mapping: Dict[str, Type[BackgroundType]] = {
|
||||
cls.FILL: BackgroundTypeFill,
|
||||
cls.WALLPAPER: BackgroundTypeWallpaper,
|
||||
cls.PATTERN: BackgroundTypePattern,
|
||||
cls.CHAT_THEME: BackgroundTypeChatTheme,
|
||||
}
|
||||
|
||||
if cls is BackgroundType and data.get("type") in _class_mapping:
|
||||
return _class_mapping[data.pop("type")].de_json(data=data, bot=bot)
|
||||
|
||||
if "fill" in data:
|
||||
data["fill"] = BackgroundFill.de_json(data.get("fill"), bot)
|
||||
|
||||
if "document" in data:
|
||||
data["document"] = Document.de_json(data.get("document"), bot)
|
||||
|
||||
return super().de_json(data=data, bot=bot)
|
||||
|
||||
|
||||
class BackgroundTypeFill(BackgroundType):
|
||||
"""
|
||||
The background is automatically filled based on the selected colors.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`fill` and :attr:`dark_theme_dimming` are equal.
|
||||
|
||||
.. versionadded:: 21.2
|
||||
|
||||
Args:
|
||||
fill (:obj:`telegram.BackgroundFill`): The background fill.
|
||||
dark_theme_dimming (:obj:`int`): Dimming of the background in dark themes, as a
|
||||
percentage;
|
||||
0-:tg-const:`telegram.constants.BackgroundTypeLimit.MAX_DIMMING`.
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): Type of the background. Always
|
||||
:attr:`~telegram.BackgroundType.FILL`.
|
||||
fill (:obj:`telegram.BackgroundFill`): The background fill.
|
||||
dark_theme_dimming (:obj:`int`): Dimming of the background in dark themes, as a
|
||||
percentage;
|
||||
0-:tg-const:`telegram.constants.BackgroundTypeLimit.MAX_DIMMING`.
|
||||
"""
|
||||
|
||||
__slots__ = ("dark_theme_dimming", "fill")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
fill: BackgroundFill,
|
||||
dark_theme_dimming: int,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(type=self.FILL, api_kwargs=api_kwargs)
|
||||
|
||||
with self._unfrozen():
|
||||
self.fill: BackgroundFill = fill
|
||||
self.dark_theme_dimming: int = dark_theme_dimming
|
||||
|
||||
self._id_attrs = (self.fill, self.dark_theme_dimming)
|
||||
|
||||
|
||||
class BackgroundTypeWallpaper(BackgroundType):
|
||||
"""
|
||||
The background is a wallpaper in the `JPEG` format.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`document` and :attr:`dark_theme_dimming` are equal.
|
||||
|
||||
.. versionadded:: 21.2
|
||||
|
||||
Args:
|
||||
document (:obj:`telegram.Document`): Document with the wallpaper
|
||||
dark_theme_dimming (:obj:`int`): Dimming of the background in dark themes, as a
|
||||
percentage;
|
||||
0-:tg-const:`telegram.constants.BackgroundTypeLimit.MAX_DIMMING`.
|
||||
is_blurred (:obj:`bool`, optional): :obj:`True`, if the wallpaper is downscaled to fit
|
||||
in a 450x450 square and then box-blurred with radius 12
|
||||
is_moving (:obj:`bool`, optional): :obj:`True`, if the background moves slightly
|
||||
when the device is tilted
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): Type of the background. Always
|
||||
:attr:`~telegram.BackgroundType.WALLPAPER`.
|
||||
document (:obj:`telegram.Document`): Document with the wallpaper
|
||||
dark_theme_dimming (:obj:`int`): Dimming of the background in dark themes, as a
|
||||
percentage;
|
||||
0-:tg-const:`telegram.constants.BackgroundTypeLimit.MAX_DIMMING`.
|
||||
is_blurred (:obj:`bool`): Optional. :obj:`True`, if the wallpaper is downscaled to fit
|
||||
in a 450x450 square and then box-blurred with radius 12
|
||||
is_moving (:obj:`bool`): Optional. :obj:`True`, if the background moves slightly
|
||||
when the device is tilted
|
||||
"""
|
||||
|
||||
__slots__ = ("dark_theme_dimming", "document", "is_blurred", "is_moving")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
document: Document,
|
||||
dark_theme_dimming: int,
|
||||
is_blurred: Optional[bool] = None,
|
||||
is_moving: Optional[bool] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(type=self.WALLPAPER, api_kwargs=api_kwargs)
|
||||
|
||||
with self._unfrozen():
|
||||
# Required
|
||||
self.document: Document = document
|
||||
self.dark_theme_dimming: int = dark_theme_dimming
|
||||
# Optionals
|
||||
self.is_blurred: Optional[bool] = is_blurred
|
||||
self.is_moving: Optional[bool] = is_moving
|
||||
|
||||
self._id_attrs = (self.document, self.dark_theme_dimming)
|
||||
|
||||
|
||||
class BackgroundTypePattern(BackgroundType):
|
||||
"""
|
||||
The background is a `PNG` or `TGV` (gzipped subset of `SVG` with `MIME` type
|
||||
`"application/x-tgwallpattern"`) pattern to be combined with the background fill
|
||||
chosen by the user.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`document` and :attr:`fill` and :attr:`intensity` are equal.
|
||||
|
||||
.. versionadded:: 21.2
|
||||
|
||||
Args:
|
||||
document (:obj:`telegram.Document`): Document with the pattern.
|
||||
fill (:obj:`telegram.BackgroundFill`): The background fill that is combined with
|
||||
the pattern.
|
||||
intensity (:obj:`int`): Intensity of the pattern when it is shown above the filled
|
||||
background;
|
||||
0-:tg-const:`telegram.constants.BackgroundTypeLimit.MAX_INTENSITY`.
|
||||
is_inverted (:obj:`int`, optional): :obj:`True`, if the background fill must be applied
|
||||
only to the pattern itself. All other pixels are black in this case. For dark
|
||||
themes only.
|
||||
is_moving (:obj:`bool`, optional): :obj:`True`, if the background moves slightly
|
||||
when the device is tilted.
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): Type of the background. Always
|
||||
:attr:`~telegram.BackgroundType.PATTERN`.
|
||||
document (:obj:`telegram.Document`): Document with the pattern.
|
||||
fill (:obj:`telegram.BackgroundFill`): The background fill that is combined with
|
||||
the pattern.
|
||||
intensity (:obj:`int`): Intensity of the pattern when it is shown above the filled
|
||||
background;
|
||||
0-:tg-const:`telegram.constants.BackgroundTypeLimit.MAX_INTENSITY`.
|
||||
is_inverted (:obj:`int`): Optional. :obj:`True`, if the background fill must be applied
|
||||
only to the pattern itself. All other pixels are black in this case. For dark
|
||||
themes only.
|
||||
is_moving (:obj:`bool`): Optional. :obj:`True`, if the background moves slightly
|
||||
when the device is tilted.
|
||||
"""
|
||||
|
||||
__slots__ = (
|
||||
"document",
|
||||
"fill",
|
||||
"intensity",
|
||||
"is_inverted",
|
||||
"is_moving",
|
||||
)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
document: Document,
|
||||
fill: BackgroundFill,
|
||||
intensity: int,
|
||||
is_inverted: Optional[bool] = None,
|
||||
is_moving: Optional[bool] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(type=self.PATTERN, api_kwargs=api_kwargs)
|
||||
|
||||
with self._unfrozen():
|
||||
# Required
|
||||
self.document: Document = document
|
||||
self.fill: BackgroundFill = fill
|
||||
self.intensity: int = intensity
|
||||
# Optionals
|
||||
self.is_inverted: Optional[bool] = is_inverted
|
||||
self.is_moving: Optional[bool] = is_moving
|
||||
|
||||
self._id_attrs = (self.document, self.fill, self.intensity)
|
||||
|
||||
|
||||
class BackgroundTypeChatTheme(BackgroundType):
|
||||
"""
|
||||
The background is taken directly from a built-in chat theme.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`theme_name` is equal.
|
||||
|
||||
.. versionadded:: 21.2
|
||||
|
||||
Args:
|
||||
theme_name (:obj:`str`): Name of the chat theme, which is usually an emoji.
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): Type of the background. Always
|
||||
:attr:`~telegram.BackgroundType.CHAT_THEME`.
|
||||
theme_name (:obj:`str`): Name of the chat theme, which is usually an emoji.
|
||||
"""
|
||||
|
||||
__slots__ = ("theme_name",)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
theme_name: str,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(type=self.CHAT_THEME, api_kwargs=api_kwargs)
|
||||
|
||||
with self._unfrozen():
|
||||
self.theme_name: str = theme_name
|
||||
|
||||
self._id_attrs = (self.theme_name,)
|
||||
|
||||
|
||||
class ChatBackground(TelegramObject):
|
||||
"""
|
||||
This object represents a chat background.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`type` is equal.
|
||||
|
||||
.. versionadded:: 21.2
|
||||
|
||||
Args:
|
||||
type (:obj:`telegram.BackgroundType`): Type of the background.
|
||||
|
||||
Attributes:
|
||||
type (:obj:`telegram.BackgroundType`): Type of the background.
|
||||
"""
|
||||
|
||||
__slots__ = ("type",)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
type: BackgroundType, # pylint: disable=redefined-builtin
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
self.type: BackgroundType = type
|
||||
|
||||
self._id_attrs = (self.type,)
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["ChatBackground"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data["type"] = BackgroundType.de_json(data.get("type"), bot)
|
||||
|
||||
return super().de_json(data=data, bot=bot)
|
||||
@@ -0,0 +1,534 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=redefined-builtin
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2024
|
||||
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram ChatFullInfo."""
|
||||
from datetime import datetime
|
||||
from typing import TYPE_CHECKING, Optional, Sequence, Tuple
|
||||
|
||||
from telegram._birthdate import Birthdate
|
||||
from telegram._chat import Chat, _ChatBase
|
||||
from telegram._chatlocation import ChatLocation
|
||||
from telegram._chatpermissions import ChatPermissions
|
||||
from telegram._files.chatphoto import ChatPhoto
|
||||
from telegram._reaction import ReactionType
|
||||
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||
from telegram._utils.datetime import extract_tzinfo_from_defaults, from_timestamp
|
||||
from telegram._utils.types import JSONDict
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import Bot, BusinessIntro, BusinessLocation, BusinessOpeningHours, Message
|
||||
|
||||
|
||||
class ChatFullInfo(_ChatBase):
|
||||
"""
|
||||
This object contains full information about a chat.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`~telegram.Chat.id` is equal.
|
||||
|
||||
.. versionadded:: 21.2
|
||||
|
||||
.. versionchanged:: 21.3
|
||||
Explicit support for all shortcut methods known from :class:`telegram.Chat` on this
|
||||
object. Previously those were only available because this class inherited from
|
||||
:class:`telegram.Chat`.
|
||||
|
||||
Args:
|
||||
id (:obj:`int`): Unique identifier for this chat.
|
||||
type (:obj:`str`): Type of chat, can be either :attr:`PRIVATE`, :attr:`GROUP`,
|
||||
:attr:`SUPERGROUP` or :attr:`CHANNEL`.
|
||||
accent_color_id (:obj:`int`, optional): Identifier of the
|
||||
:class:`accent color <telegram.constants.AccentColor>` for the chat name and
|
||||
backgrounds of the chat photo, reply header, and link preview. See `accent colors`_
|
||||
for more details.
|
||||
|
||||
.. versionadded:: 20.8
|
||||
max_reaction_count (:obj:`int`): The maximum number of reactions that can be set on a
|
||||
message in the chat.
|
||||
|
||||
.. versionadded:: 21.2
|
||||
title (:obj:`str`, optional): Title, for supergroups, channels and group chats.
|
||||
username (:obj:`str`, optional): Username, for private chats, supergroups and channels if
|
||||
available.
|
||||
first_name (:obj:`str`, optional): First name of the other party in a private chat.
|
||||
last_name (:obj:`str`, optional): Last name of the other party in a private chat.
|
||||
is_forum (:obj:`bool`, optional): :obj:`True`, if the supergroup chat is a forum
|
||||
(has topics_ enabled).
|
||||
|
||||
.. versionadded:: 20.0
|
||||
photo (:class:`telegram.ChatPhoto`, optional): Chat photo.
|
||||
active_usernames (Sequence[:obj:`str`], optional): If set, the list of all `active chat
|
||||
usernames <https://telegram.org/blog/topics-in-groups-collectible-usernames\
|
||||
#collectible-usernames>`_; for private chats, supergroups and channels.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
birthdate (:obj:`telegram.Birthdate`, optional): For private chats,
|
||||
the date of birth of the user.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
business_intro (:class:`telegram.BusinessIntro`, optional): For private chats with
|
||||
business accounts, the intro of the business.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
business_location (:class:`telegram.BusinessLocation`, optional): For private chats with
|
||||
business accounts, the location of the business.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
business_opening_hours (:class:`telegram.BusinessOpeningHours`, optional): For private
|
||||
chats with business accounts, the opening hours of the business.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
personal_chat (:obj:`telegram.Chat`, optional): For private chats, the personal channel of
|
||||
the user.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
available_reactions (Sequence[:class:`telegram.ReactionType`], optional): List of available
|
||||
reactions allowed in the chat. If omitted, then all of
|
||||
:const:`telegram.constants.ReactionEmoji` are allowed.
|
||||
|
||||
.. versionadded:: 20.8
|
||||
background_custom_emoji_id (:obj:`str`, optional): Custom emoji identifier of emoji chosen
|
||||
by the chat for the reply header and link preview background.
|
||||
|
||||
.. versionadded:: 20.8
|
||||
profile_accent_color_id (:obj:`int`, optional): Identifier of the
|
||||
:class:`accent color <telegram.constants.ProfileAccentColor>` for the chat's profile
|
||||
background. See profile `accent colors`_ for more details.
|
||||
|
||||
.. versionadded:: 20.8
|
||||
profile_background_custom_emoji_id (:obj:`str`, optional): Custom emoji identifier of
|
||||
the emoji chosen by the chat for its profile background.
|
||||
|
||||
.. versionadded:: 20.8
|
||||
emoji_status_custom_emoji_id (:obj:`str`, optional): Custom emoji identifier of emoji
|
||||
status of the chat or the other party in a private chat.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
emoji_status_expiration_date (:class:`datetime.datetime`, optional): Expiration date of
|
||||
emoji status of the chat or the other party in a private chat, in seconds.
|
||||
|
||||
|datetime_localization|
|
||||
|
||||
.. versionadded:: 20.5
|
||||
bio (:obj:`str`, optional): Bio of the other party in a private chat.
|
||||
has_private_forwards (:obj:`bool`, optional): :obj:`True`, if privacy settings of the other
|
||||
party in the private chat allows to use ``tg://user?id=<user_id>`` links only in chats
|
||||
with the user.
|
||||
|
||||
.. versionadded:: 13.9
|
||||
has_restricted_voice_and_video_messages (:obj:`bool`, optional): :obj:`True`, if the
|
||||
privacy settings of the other party restrict sending voice and video note messages
|
||||
in the private chat.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
join_to_send_messages (:obj:`bool`, optional): :obj:`True`, if users need to join the
|
||||
supergroup before they can send messages.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
join_by_request (:obj:`bool`, optional): :obj:`True`, if all users directly joining the
|
||||
supergroup without using an invite link need to be approved by supergroup
|
||||
administrators.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
description (:obj:`str`, optional): Description, for groups, supergroups and channel chats.
|
||||
invite_link (:obj:`str`, optional): Primary invite link, for groups, supergroups and
|
||||
channel.
|
||||
pinned_message (:class:`telegram.Message`, optional): The most recent pinned message
|
||||
(by sending date).
|
||||
permissions (:class:`telegram.ChatPermissions`): Optional. Default chat member permissions,
|
||||
for groups and supergroups.
|
||||
slow_mode_delay (:obj:`int`, optional): For supergroups, the minimum allowed delay between
|
||||
consecutive messages sent by each unprivileged user.
|
||||
unrestrict_boost_count (:obj:`int`, optional): For supergroups, the minimum number of
|
||||
boosts that a non-administrator user needs to add in order to ignore slow mode and chat
|
||||
permissions.
|
||||
|
||||
.. versionadded:: 21.0
|
||||
message_auto_delete_time (:obj:`int`, optional): The time after which all messages sent to
|
||||
the chat will be automatically deleted; in seconds.
|
||||
|
||||
.. versionadded:: 13.4
|
||||
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.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
has_hidden_members (:obj:`bool`, optional): :obj:`True`, if non-administrators can only
|
||||
get the list of bots and administrators in the chat.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
has_protected_content (:obj:`bool`, optional): :obj:`True`, if messages from the chat can't
|
||||
be forwarded to other chats.
|
||||
|
||||
.. versionadded:: 13.9
|
||||
has_visible_history (:obj:`bool`, optional): :obj:`True`, if new chat members will have
|
||||
access to old messages; available only to chat administrators.
|
||||
|
||||
.. versionadded:: 20.8
|
||||
sticker_set_name (:obj:`str`, optional): For supergroups, name of group sticker set.
|
||||
can_set_sticker_set (:obj:`bool`, optional): :obj:`True`, if the bot can change group the
|
||||
sticker set.
|
||||
custom_emoji_sticker_set_name (:obj:`str`, optional): For supergroups, the name of the
|
||||
group's custom emoji sticker set. Custom emoji from this set can be used by all users
|
||||
and bots in the group.
|
||||
|
||||
.. versionadded:: 21.0
|
||||
linked_chat_id (:obj:`int`, optional): Unique identifier for the linked chat, i.e. the
|
||||
discussion group identifier for a channel and vice versa; for supergroups and channel
|
||||
chats.
|
||||
location (:class:`telegram.ChatLocation`, optional): For supergroups, the location to which
|
||||
the supergroup is connected.
|
||||
|
||||
Attributes:
|
||||
id (:obj:`int`): Unique identifier for this chat.
|
||||
type (:obj:`str`): Type of chat, can be either :attr:`PRIVATE`, :attr:`GROUP`,
|
||||
:attr:`SUPERGROUP` or :attr:`CHANNEL`.
|
||||
accent_color_id (:obj:`int`): Optional. Identifier of the
|
||||
:class:`accent color <telegram.constants.AccentColor>` for the chat name and
|
||||
backgrounds of the chat photo, reply header, and link preview. See `accent colors`_
|
||||
for more details.
|
||||
|
||||
.. versionadded:: 20.8
|
||||
max_reaction_count (:obj:`int`): The maximum number of reactions that can be set on a
|
||||
message in the chat.
|
||||
|
||||
.. versionadded:: 21.2
|
||||
title (:obj:`str`, optional): Title, for supergroups, channels and group chats.
|
||||
username (:obj:`str`, optional): Username, for private chats, supergroups and channels if
|
||||
available.
|
||||
first_name (:obj:`str`, optional): First name of the other party in a private chat.
|
||||
last_name (:obj:`str`, optional): Last name of the other party in a private chat.
|
||||
is_forum (:obj:`bool`, optional): :obj:`True`, if the supergroup chat is a forum
|
||||
(has topics_ enabled).
|
||||
|
||||
.. versionadded:: 20.0
|
||||
photo (:class:`telegram.ChatPhoto`): Optional. Chat photo.
|
||||
active_usernames (Tuple[:obj:`str`]): Optional. If set, the list of all `active chat
|
||||
usernames <https://telegram.org/blog/topics-in-groups-collectible-usernames\
|
||||
#collectible-usernames>`_; for private chats, supergroups and channels.
|
||||
|
||||
This list is empty if the chat has no active usernames or this chat instance was not
|
||||
obtained via :meth:`~telegram.Bot.get_chat`.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
birthdate (:obj:`telegram.Birthdate`): Optional. For private chats,
|
||||
the date of birth of the user.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
business_intro (:class:`telegram.BusinessIntro`): Optional. For private chats with
|
||||
business accounts, the intro of the business.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
business_location (:class:`telegram.BusinessLocation`): Optional. For private chats with
|
||||
business accounts, the location of the business.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
business_opening_hours (:class:`telegram.BusinessOpeningHours`): Optional. For private
|
||||
chats with business accounts, the opening hours of the business.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
personal_chat (:obj:`telegram.Chat`): Optional. For private chats, the personal channel of
|
||||
the user.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
available_reactions (Tuple[:class:`telegram.ReactionType`]): Optional. List of available
|
||||
reactions allowed in the chat. If omitted, then all of
|
||||
:const:`telegram.constants.ReactionEmoji` are allowed.
|
||||
|
||||
.. versionadded:: 20.8
|
||||
background_custom_emoji_id (:obj:`str`): Optional. Custom emoji identifier of emoji chosen
|
||||
by the chat for the reply header and link preview background.
|
||||
|
||||
.. versionadded:: 20.8
|
||||
profile_accent_color_id (:obj:`int`): Optional. Identifier of the
|
||||
:class:`accent color <telegram.constants.ProfileAccentColor>` for the chat's profile
|
||||
background. See profile `accent colors`_ for more details.
|
||||
|
||||
.. versionadded:: 20.8
|
||||
profile_background_custom_emoji_id (:obj:`str`): Optional. Custom emoji identifier of
|
||||
the emoji chosen by the chat for its profile background.
|
||||
|
||||
.. versionadded:: 20.8
|
||||
emoji_status_custom_emoji_id (:obj:`str`): Optional. Custom emoji identifier of emoji
|
||||
status of the chat or the other party in a private chat.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
emoji_status_expiration_date (:class:`datetime.datetime`): Optional. Expiration date of
|
||||
emoji status of the chat or the other party in a private chat, in seconds.
|
||||
|
||||
|datetime_localization|
|
||||
|
||||
.. versionadded:: 20.5
|
||||
bio (:obj:`str`): Optional. Bio of the other party in a private chat.
|
||||
has_private_forwards (:obj:`bool`): Optional. :obj:`True`, if privacy settings of the other
|
||||
party in the private chat allows to use ``tg://user?id=<user_id>`` links only in chats
|
||||
with the user.
|
||||
|
||||
.. versionadded:: 13.9
|
||||
has_restricted_voice_and_video_messages (:obj:`bool`): Optional. :obj:`True`, if the
|
||||
privacy settings of the other party restrict sending voice and video note messages
|
||||
in the private chat.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
join_to_send_messages (:obj:`bool`): Optional. :obj:`True`, if users need to join
|
||||
the supergroup before they can send messages.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
join_by_request (:obj:`bool`): Optional. :obj:`True`, if all users directly joining the
|
||||
supergroup without using an invite link need to be approved by supergroup
|
||||
administrators.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
description (:obj:`str`): Optional. Description, for groups, supergroups and channel chats.
|
||||
invite_link (:obj:`str`): Optional. Primary invite link, for groups, supergroups and
|
||||
channel.
|
||||
pinned_message (:class:`telegram.Message`): Optional. The most recent pinned message
|
||||
(by sending date).
|
||||
permissions (:class:`telegram.ChatPermissions`): Optional. Default chat member permissions,
|
||||
for groups and supergroups.
|
||||
slow_mode_delay (:obj:`int`): Optional. For supergroups, the minimum allowed delay between
|
||||
consecutive messages sent by each unprivileged user.
|
||||
unrestrict_boost_count (:obj:`int`): Optional. For supergroups, the minimum number of
|
||||
boosts that a non-administrator user needs to add in order to ignore slow mode and chat
|
||||
permissions.
|
||||
|
||||
.. versionadded:: 21.0
|
||||
message_auto_delete_time (:obj:`int`): Optional. The time after which all messages sent to
|
||||
the chat will be automatically deleted; in seconds.
|
||||
|
||||
.. versionadded:: 13.4
|
||||
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.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
has_hidden_members (:obj:`bool`): Optional. :obj:`True`, if non-administrators can only
|
||||
get the list of bots and administrators in the chat.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
has_protected_content (:obj:`bool`): Optional. :obj:`True`, if messages from the chat can't
|
||||
be forwarded to other chats.
|
||||
|
||||
.. versionadded:: 13.9
|
||||
has_visible_history (:obj:`bool`): Optional. :obj:`True`, if new chat members will have
|
||||
access to old messages; available only to chat administrators.
|
||||
|
||||
.. versionadded:: 20.8
|
||||
sticker_set_name (:obj:`str`): Optional. For supergroups, name of Group sticker set.
|
||||
can_set_sticker_set (:obj:`bool`): Optional. :obj:`True`, if the bot can change group the
|
||||
sticker set.
|
||||
custom_emoji_sticker_set_name (:obj:`str`): Optional. For supergroups, the name of the
|
||||
group's custom emoji sticker set. Custom emoji from this set can be used by all users
|
||||
and bots in the group.
|
||||
|
||||
.. versionadded:: 21.0
|
||||
linked_chat_id (:obj:`int`): Optional. Unique identifier for the linked chat, i.e. the
|
||||
discussion group identifier for a channel and vice versa; for supergroups and channel
|
||||
chats.
|
||||
location (:class:`telegram.ChatLocation`): Optional. For supergroups, the location to which
|
||||
the supergroup is connected.
|
||||
|
||||
.. _accent colors: https://core.telegram.org/bots/api#accent-colors
|
||||
.. _topics: https://telegram.org/blog/topics-in-groups-collectible-usernames#topics-in-groups
|
||||
"""
|
||||
|
||||
__slots__ = (
|
||||
"accent_color_id",
|
||||
"active_usernames",
|
||||
"available_reactions",
|
||||
"background_custom_emoji_id",
|
||||
"bio",
|
||||
"birthdate",
|
||||
"business_intro",
|
||||
"business_location",
|
||||
"business_opening_hours",
|
||||
"can_set_sticker_set",
|
||||
"custom_emoji_sticker_set_name",
|
||||
"description",
|
||||
"emoji_status_custom_emoji_id",
|
||||
"emoji_status_expiration_date",
|
||||
"has_aggressive_anti_spam_enabled",
|
||||
"has_hidden_members",
|
||||
"has_private_forwards",
|
||||
"has_protected_content",
|
||||
"has_restricted_voice_and_video_messages",
|
||||
"has_visible_history",
|
||||
"invite_link",
|
||||
"join_by_request",
|
||||
"join_to_send_messages",
|
||||
"linked_chat_id",
|
||||
"location",
|
||||
"max_reaction_count",
|
||||
"message_auto_delete_time",
|
||||
"permissions",
|
||||
"personal_chat",
|
||||
"photo",
|
||||
"pinned_message",
|
||||
"profile_accent_color_id",
|
||||
"profile_background_custom_emoji_id",
|
||||
"slow_mode_delay",
|
||||
"sticker_set_name",
|
||||
"unrestrict_boost_count",
|
||||
)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
id: int,
|
||||
type: str,
|
||||
accent_color_id: int,
|
||||
max_reaction_count: int,
|
||||
title: Optional[str] = None,
|
||||
username: Optional[str] = None,
|
||||
first_name: Optional[str] = None,
|
||||
last_name: Optional[str] = None,
|
||||
is_forum: Optional[bool] = None,
|
||||
photo: Optional[ChatPhoto] = None,
|
||||
active_usernames: Optional[Sequence[str]] = None,
|
||||
birthdate: Optional[Birthdate] = None,
|
||||
business_intro: Optional["BusinessIntro"] = None,
|
||||
business_location: Optional["BusinessLocation"] = None,
|
||||
business_opening_hours: Optional["BusinessOpeningHours"] = None,
|
||||
personal_chat: Optional["Chat"] = None,
|
||||
available_reactions: Optional[Sequence[ReactionType]] = None,
|
||||
background_custom_emoji_id: Optional[str] = None,
|
||||
profile_accent_color_id: Optional[int] = None,
|
||||
profile_background_custom_emoji_id: Optional[str] = None,
|
||||
emoji_status_custom_emoji_id: Optional[str] = None,
|
||||
emoji_status_expiration_date: Optional[datetime] = None,
|
||||
bio: Optional[str] = None,
|
||||
has_private_forwards: Optional[bool] = None,
|
||||
has_restricted_voice_and_video_messages: Optional[bool] = None,
|
||||
join_to_send_messages: Optional[bool] = None,
|
||||
join_by_request: Optional[bool] = None,
|
||||
description: Optional[str] = None,
|
||||
invite_link: Optional[str] = None,
|
||||
pinned_message: Optional["Message"] = None,
|
||||
permissions: Optional[ChatPermissions] = None,
|
||||
slow_mode_delay: Optional[int] = None,
|
||||
unrestrict_boost_count: Optional[int] = None,
|
||||
message_auto_delete_time: Optional[int] = None,
|
||||
has_aggressive_anti_spam_enabled: Optional[bool] = None,
|
||||
has_hidden_members: Optional[bool] = None,
|
||||
has_protected_content: Optional[bool] = None,
|
||||
has_visible_history: Optional[bool] = None,
|
||||
sticker_set_name: Optional[str] = None,
|
||||
can_set_sticker_set: Optional[bool] = None,
|
||||
custom_emoji_sticker_set_name: Optional[str] = None,
|
||||
linked_chat_id: Optional[int] = None,
|
||||
location: Optional[ChatLocation] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(
|
||||
id=id,
|
||||
type=type,
|
||||
title=title,
|
||||
username=username,
|
||||
first_name=first_name,
|
||||
last_name=last_name,
|
||||
is_forum=is_forum,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
# Required and unique to this class-
|
||||
with self._unfrozen():
|
||||
self.max_reaction_count: int = max_reaction_count
|
||||
self.photo: Optional[ChatPhoto] = photo
|
||||
self.bio: Optional[str] = bio
|
||||
self.has_private_forwards: Optional[bool] = has_private_forwards
|
||||
self.description: Optional[str] = description
|
||||
self.invite_link: Optional[str] = invite_link
|
||||
self.pinned_message: Optional[Message] = pinned_message
|
||||
self.permissions: Optional[ChatPermissions] = permissions
|
||||
self.slow_mode_delay: Optional[int] = slow_mode_delay
|
||||
self.message_auto_delete_time: Optional[int] = (
|
||||
int(message_auto_delete_time) if message_auto_delete_time is not None else None
|
||||
)
|
||||
self.has_protected_content: Optional[bool] = has_protected_content
|
||||
self.has_visible_history: Optional[bool] = has_visible_history
|
||||
self.sticker_set_name: Optional[str] = sticker_set_name
|
||||
self.can_set_sticker_set: Optional[bool] = can_set_sticker_set
|
||||
self.linked_chat_id: Optional[int] = linked_chat_id
|
||||
self.location: Optional[ChatLocation] = location
|
||||
self.join_to_send_messages: Optional[bool] = join_to_send_messages
|
||||
self.join_by_request: Optional[bool] = join_by_request
|
||||
self.has_restricted_voice_and_video_messages: Optional[bool] = (
|
||||
has_restricted_voice_and_video_messages
|
||||
)
|
||||
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
|
||||
self.available_reactions: Optional[Tuple[ReactionType, ...]] = parse_sequence_arg(
|
||||
available_reactions
|
||||
)
|
||||
self.accent_color_id: Optional[int] = accent_color_id
|
||||
self.background_custom_emoji_id: Optional[str] = background_custom_emoji_id
|
||||
self.profile_accent_color_id: Optional[int] = profile_accent_color_id
|
||||
self.profile_background_custom_emoji_id: Optional[str] = (
|
||||
profile_background_custom_emoji_id
|
||||
)
|
||||
self.unrestrict_boost_count: Optional[int] = unrestrict_boost_count
|
||||
self.custom_emoji_sticker_set_name: Optional[str] = custom_emoji_sticker_set_name
|
||||
self.birthdate: Optional[Birthdate] = birthdate
|
||||
self.personal_chat: Optional["Chat"] = personal_chat
|
||||
self.business_intro: Optional["BusinessIntro"] = business_intro
|
||||
self.business_location: Optional["BusinessLocation"] = business_location
|
||||
self.business_opening_hours: Optional["BusinessOpeningHours"] = business_opening_hours
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["ChatFullInfo"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
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 ( # pylint: disable=import-outside-toplevel
|
||||
BusinessIntro,
|
||||
BusinessLocation,
|
||||
BusinessOpeningHours,
|
||||
Message,
|
||||
)
|
||||
|
||||
data["pinned_message"] = Message.de_json(data.get("pinned_message"), bot)
|
||||
data["permissions"] = ChatPermissions.de_json(data.get("permissions"), bot)
|
||||
data["location"] = ChatLocation.de_json(data.get("location"), bot)
|
||||
data["available_reactions"] = ReactionType.de_list(data.get("available_reactions"), bot)
|
||||
data["birthdate"] = Birthdate.de_json(data.get("birthdate"), bot)
|
||||
data["personal_chat"] = Chat.de_json(data.get("personal_chat"), bot)
|
||||
data["business_intro"] = BusinessIntro.de_json(data.get("business_intro"), bot)
|
||||
data["business_location"] = BusinessLocation.de_json(data.get("business_location"), bot)
|
||||
data["business_opening_hours"] = BusinessOpeningHours.de_json(
|
||||
data.get("business_opening_hours"), bot
|
||||
)
|
||||
|
||||
return super().de_json(data=data, bot=bot)
|
||||
+14
-13
@@ -191,6 +191,11 @@ class ChatMemberAdministrator(ChatMember):
|
||||
* The argument :paramref:`can_manage_topics` was added, which changes the position of the
|
||||
optional argument :paramref:`custom_title`.
|
||||
|
||||
.. versionchanged:: 21.1
|
||||
As of this version, :attr:`can_post_stories`, :attr:`can_edit_stories`,
|
||||
and :attr:`can_delete_stories` is now required. Thus, the order of arguments had to be
|
||||
changed.
|
||||
|
||||
Args:
|
||||
user (:class:`telegram.User`): Information about the user.
|
||||
can_be_edited (:obj:`bool`): :obj:`True`, if the bot
|
||||
@@ -230,8 +235,9 @@ class ChatMemberAdministrator(ChatMember):
|
||||
.. versionadded:: 20.6
|
||||
.. versionchanged:: 21.0
|
||||
|non_optional_story_argument|
|
||||
can_edit_stories (:obj:`bool`): :obj:`True`, if the administrator can edit
|
||||
stories posted by other users.
|
||||
can_edit_stories (:obj:`bool`): :obj:`True`, if the administrator can edit stories posted
|
||||
by other users, post stories to the chat page, pin chat stories, and access the chat's
|
||||
story archive
|
||||
|
||||
.. versionadded:: 20.6
|
||||
.. versionchanged:: 21.0
|
||||
@@ -289,8 +295,9 @@ class ChatMemberAdministrator(ChatMember):
|
||||
.. versionadded:: 20.6
|
||||
.. versionchanged:: 21.0
|
||||
|non_optional_story_argument|
|
||||
can_edit_stories (:obj:`bool`): :obj:`True`, if the administrator can edit
|
||||
stories posted by other users.
|
||||
can_edit_stories (:obj:`bool`): :obj:`True`, if the administrator can edit stories posted
|
||||
by other users, post stories to the chat page, pin chat stories, and access the chat's
|
||||
story archive
|
||||
|
||||
.. versionadded:: 20.6
|
||||
.. versionchanged:: 21.0
|
||||
@@ -340,14 +347,14 @@ class ChatMemberAdministrator(ChatMember):
|
||||
can_promote_members: bool,
|
||||
can_change_info: bool,
|
||||
can_invite_users: bool,
|
||||
can_post_stories: bool,
|
||||
can_edit_stories: bool,
|
||||
can_delete_stories: bool,
|
||||
can_post_messages: Optional[bool] = None,
|
||||
can_edit_messages: Optional[bool] = None,
|
||||
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,
|
||||
):
|
||||
@@ -362,12 +369,6 @@ class ChatMemberAdministrator(ChatMember):
|
||||
self.can_promote_members: bool = can_promote_members
|
||||
self.can_change_info: bool = can_change_info
|
||||
self.can_invite_users: bool = can_invite_users
|
||||
# Not actually optionals but because of backwards compatability we pretend they are
|
||||
if can_post_stories is None or can_edit_stories is None or can_delete_stories is None:
|
||||
raise TypeError(
|
||||
"As of 21.0 can_post_stories, can_edit_stories and can_delete_stories "
|
||||
"must be set in order to create this object."
|
||||
)
|
||||
self.can_post_stories: bool = can_post_stories
|
||||
self.can_edit_stories: bool = can_edit_stories
|
||||
self.can_delete_stories: bool = can_delete_stories
|
||||
|
||||
@@ -63,6 +63,11 @@ class ChatMemberUpdated(TelegramObject):
|
||||
chat via a chat folder invite link
|
||||
|
||||
.. versionadded:: 20.3
|
||||
via_join_request (:obj:`bool`, optional): :obj:`True`, if the user joined the chat after
|
||||
sending a direct join request without using an invite link and being approved by
|
||||
an administrator
|
||||
|
||||
.. versionadded:: 21.2
|
||||
|
||||
Attributes:
|
||||
chat (:class:`telegram.Chat`): Chat the user belongs to.
|
||||
@@ -80,6 +85,11 @@ class ChatMemberUpdated(TelegramObject):
|
||||
chat via a chat folder invite link
|
||||
|
||||
.. versionadded:: 20.3
|
||||
via_join_request (:obj:`bool`): Optional. :obj:`True`, if the user joined the chat after
|
||||
sending a direct join request without using an invite link and being approved
|
||||
by an administrator
|
||||
|
||||
.. versionadded:: 21.2
|
||||
|
||||
"""
|
||||
|
||||
@@ -91,6 +101,7 @@ class ChatMemberUpdated(TelegramObject):
|
||||
"new_chat_member",
|
||||
"old_chat_member",
|
||||
"via_chat_folder_invite_link",
|
||||
"via_join_request",
|
||||
)
|
||||
|
||||
def __init__(
|
||||
@@ -102,6 +113,7 @@ class ChatMemberUpdated(TelegramObject):
|
||||
new_chat_member: ChatMember,
|
||||
invite_link: Optional[ChatInviteLink] = None,
|
||||
via_chat_folder_invite_link: Optional[bool] = None,
|
||||
via_join_request: Optional[bool] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
@@ -116,6 +128,7 @@ class ChatMemberUpdated(TelegramObject):
|
||||
|
||||
# Optionals
|
||||
self.invite_link: Optional[ChatInviteLink] = invite_link
|
||||
self.via_join_request: Optional[bool] = via_join_request
|
||||
|
||||
self._id_attrs = (
|
||||
self.chat,
|
||||
|
||||
@@ -160,6 +160,9 @@ class InputMediaAnimation(InputMedia):
|
||||
optional): |thumbdocstringnopath|
|
||||
|
||||
.. versionadded:: 20.2
|
||||
show_caption_above_media (:obj:`bool`, optional): Pass |show_cap_above_med|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): :tg-const:`telegram.constants.InputMediaType.ANIMATION`.
|
||||
@@ -184,9 +187,19 @@ class InputMediaAnimation(InputMedia):
|
||||
thumbnail (:class:`telegram.InputFile`): Optional. |thumbdocstringbase|
|
||||
|
||||
.. versionadded:: 20.2
|
||||
show_caption_above_media (:obj:`bool`): Optional. |show_cap_above_med|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
"""
|
||||
|
||||
__slots__ = ("duration", "has_spoiler", "height", "thumbnail", "width")
|
||||
__slots__ = (
|
||||
"duration",
|
||||
"has_spoiler",
|
||||
"height",
|
||||
"show_caption_above_media",
|
||||
"thumbnail",
|
||||
"width",
|
||||
)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@@ -200,6 +213,7 @@ class InputMediaAnimation(InputMedia):
|
||||
filename: Optional[str] = None,
|
||||
has_spoiler: Optional[bool] = None,
|
||||
thumbnail: Optional[FileInput] = None,
|
||||
show_caption_above_media: Optional[bool] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
@@ -229,6 +243,7 @@ class InputMediaAnimation(InputMedia):
|
||||
self.height: Optional[int] = height
|
||||
self.duration: Optional[int] = duration
|
||||
self.has_spoiler: Optional[bool] = has_spoiler
|
||||
self.show_caption_above_media: Optional[bool] = show_caption_above_media
|
||||
|
||||
|
||||
class InputMediaPhoto(InputMedia):
|
||||
@@ -260,6 +275,9 @@ class InputMediaPhoto(InputMedia):
|
||||
with a spoiler animation.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
show_caption_above_media (:obj:`bool`, optional): Pass |show_cap_above_med|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): :tg-const:`telegram.constants.InputMediaType.PHOTO`.
|
||||
@@ -278,9 +296,15 @@ class InputMediaPhoto(InputMedia):
|
||||
spoiler animation.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
show_caption_above_media (:obj:`bool`): Optional. |show_cap_above_med|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
"""
|
||||
|
||||
__slots__ = ("has_spoiler",)
|
||||
__slots__ = (
|
||||
"has_spoiler",
|
||||
"show_caption_above_media",
|
||||
)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@@ -290,6 +314,7 @@ class InputMediaPhoto(InputMedia):
|
||||
caption_entities: Optional[Sequence[MessageEntity]] = None,
|
||||
filename: Optional[str] = None,
|
||||
has_spoiler: Optional[bool] = None,
|
||||
show_caption_above_media: Optional[bool] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
@@ -307,6 +332,7 @@ class InputMediaPhoto(InputMedia):
|
||||
|
||||
with self._unfrozen():
|
||||
self.has_spoiler: Optional[bool] = has_spoiler
|
||||
self.show_caption_above_media: Optional[bool] = show_caption_above_media
|
||||
|
||||
|
||||
class InputMediaVideo(InputMedia):
|
||||
@@ -359,6 +385,9 @@ class InputMediaVideo(InputMedia):
|
||||
optional): |thumbdocstringnopath|
|
||||
|
||||
.. versionadded:: 20.2
|
||||
show_caption_above_media (:obj:`bool`, optional): Pass |show_cap_above_med|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): :tg-const:`telegram.constants.InputMediaType.VIDEO`.
|
||||
@@ -385,12 +414,16 @@ class InputMediaVideo(InputMedia):
|
||||
thumbnail (:class:`telegram.InputFile`): Optional. |thumbdocstringbase|
|
||||
|
||||
.. versionadded:: 20.2
|
||||
show_caption_above_media (:obj:`bool`): Optional. |show_cap_above_med|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
"""
|
||||
|
||||
__slots__ = (
|
||||
"duration",
|
||||
"has_spoiler",
|
||||
"height",
|
||||
"show_caption_above_media",
|
||||
"supports_streaming",
|
||||
"thumbnail",
|
||||
"width",
|
||||
@@ -409,6 +442,7 @@ class InputMediaVideo(InputMedia):
|
||||
filename: Optional[str] = None,
|
||||
has_spoiler: Optional[bool] = None,
|
||||
thumbnail: Optional[FileInput] = None,
|
||||
show_caption_above_media: Optional[bool] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
@@ -439,6 +473,7 @@ class InputMediaVideo(InputMedia):
|
||||
)
|
||||
self.supports_streaming: Optional[bool] = supports_streaming
|
||||
self.has_spoiler: Optional[bool] = has_spoiler
|
||||
self.show_caption_above_media: Optional[bool] = show_caption_above_media
|
||||
|
||||
|
||||
class InputMediaAudio(InputMedia):
|
||||
|
||||
@@ -36,6 +36,10 @@ class InputSticker(TelegramObject):
|
||||
|
||||
.. versionadded:: 20.2
|
||||
|
||||
.. versionchanged:: 21.1
|
||||
As of Bot API 7.2, the new argument :paramref:`format` is a required argument, and thus the
|
||||
order of the arguments has changed.
|
||||
|
||||
Args:
|
||||
sticker (:obj:`str` | :term:`file object` | :obj:`bytes` | :class:`pathlib.Path`): The
|
||||
added sticker. |uploadinputnopath| Animated and video stickers can't be uploaded via
|
||||
@@ -52,6 +56,13 @@ class InputSticker(TelegramObject):
|
||||
:tg-const:`telegram.constants.StickerLimit.MAX_KEYWORD_LENGTH` characters. For
|
||||
":tg-const:`telegram.constants.StickerType.REGULAR`" and
|
||||
":tg-const:`telegram.constants.StickerType.CUSTOM_EMOJI`" stickers only.
|
||||
format (:obj:`str`): Format of the added sticker, must be one of
|
||||
:tg-const:`telegram.constants.StickerFormat.STATIC` for a
|
||||
``.WEBP`` or ``.PNG`` image, :tg-const:`telegram.constants.StickerFormat.ANIMATED`
|
||||
for a ``.TGS`` animation, :tg-const:`telegram.constants.StickerFormat.VIDEO` for a WEBM
|
||||
video.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
|
||||
Attributes:
|
||||
sticker (:obj:`str` | :class:`telegram.InputFile`): The added sticker.
|
||||
@@ -67,15 +78,23 @@ class InputSticker(TelegramObject):
|
||||
:tg-const:`telegram.constants.StickerLimit.MAX_KEYWORD_LENGTH` characters. For
|
||||
":tg-const:`telegram.constants.StickerType.REGULAR`" and
|
||||
":tg-const:`telegram.constants.StickerType.CUSTOM_EMOJI`" stickers only.
|
||||
":tg-const:`telegram.constants.StickerType.CUSTOM_EMOJI`" stickers only.
|
||||
format (:obj:`str`): Format of the added sticker, must be one of
|
||||
:tg-const:`telegram.constants.StickerFormat.STATIC` for a
|
||||
``.WEBP`` or ``.PNG`` image, :tg-const:`telegram.constants.StickerFormat.ANIMATED`
|
||||
for a ``.TGS`` animation, :tg-const:`telegram.constants.StickerFormat.VIDEO` for a WEBM
|
||||
video.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
"""
|
||||
|
||||
__slots__ = ("emoji_list", "keywords", "mask_position", "sticker")
|
||||
__slots__ = ("emoji_list", "format", "keywords", "mask_position", "sticker")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
sticker: FileInput,
|
||||
emoji_list: Sequence[str],
|
||||
format: str, # pylint: disable=redefined-builtin
|
||||
mask_position: Optional[MaskPosition] = None,
|
||||
keywords: Optional[Sequence[str]] = None,
|
||||
*,
|
||||
@@ -91,6 +110,7 @@ class InputSticker(TelegramObject):
|
||||
attach=True,
|
||||
)
|
||||
self.emoji_list: Tuple[str, ...] = parse_sequence_arg(emoji_list)
|
||||
self.format: str = format
|
||||
self.mask_position: Optional[MaskPosition] = mask_position
|
||||
self.keywords: Tuple[str, ...] = parse_sequence_arg(keywords)
|
||||
|
||||
|
||||
@@ -227,16 +227,20 @@ class StickerSet(TelegramObject):
|
||||
.. versionchanged:: 20.0
|
||||
The parameter ``contains_masks`` has been removed. Use :paramref:`sticker_type` instead.
|
||||
|
||||
|
||||
.. versionchanged:: 21.1
|
||||
The parameters ``is_video`` and ``is_animated`` are deprecated and now made optional. Thus,
|
||||
the order of the arguments had to be changed.
|
||||
|
||||
.. versionchanged:: 20.5
|
||||
|removed_thumb_note|
|
||||
|
||||
.. versionremoved:: 21.2
|
||||
Removed the deprecated arguments and attributes ``is_animated`` and ``is_video``.
|
||||
|
||||
Args:
|
||||
name (:obj:`str`): Sticker set name.
|
||||
title (:obj:`str`): Sticker set title.
|
||||
is_animated (:obj:`bool`): :obj:`True`, if the sticker set contains animated stickers.
|
||||
is_video (:obj:`bool`): :obj:`True`, if the sticker set contains video stickers.
|
||||
|
||||
.. versionadded:: 13.11
|
||||
stickers (Sequence[:class:`telegram.Sticker`]): List of all set stickers.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
@@ -255,10 +259,6 @@ class StickerSet(TelegramObject):
|
||||
Attributes:
|
||||
name (:obj:`str`): Sticker set name.
|
||||
title (:obj:`str`): Sticker set title.
|
||||
is_animated (:obj:`bool`): :obj:`True`, if the sticker set contains animated stickers.
|
||||
is_video (:obj:`bool`): :obj:`True`, if the sticker set contains video stickers.
|
||||
|
||||
.. versionadded:: 13.11
|
||||
stickers (Tuple[:class:`telegram.Sticker`]): List of all set stickers.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
@@ -276,8 +276,6 @@ class StickerSet(TelegramObject):
|
||||
"""
|
||||
|
||||
__slots__ = (
|
||||
"is_animated",
|
||||
"is_video",
|
||||
"name",
|
||||
"sticker_type",
|
||||
"stickers",
|
||||
@@ -289,9 +287,7 @@ class StickerSet(TelegramObject):
|
||||
self,
|
||||
name: str,
|
||||
title: str,
|
||||
is_animated: bool,
|
||||
stickers: Sequence[Sticker],
|
||||
is_video: bool,
|
||||
sticker_type: str,
|
||||
thumbnail: Optional[PhotoSize] = None,
|
||||
*,
|
||||
@@ -300,12 +296,9 @@ class StickerSet(TelegramObject):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
self.name: str = name
|
||||
self.title: str = title
|
||||
self.is_animated: bool = is_animated
|
||||
self.is_video: bool = is_video
|
||||
self.stickers: Tuple[Sticker, ...] = parse_sequence_arg(stickers)
|
||||
self.sticker_type: str = sticker_type
|
||||
# Optional
|
||||
|
||||
self.thumbnail: Optional[PhotoSize] = thumbnail
|
||||
self._id_attrs = (self.name,)
|
||||
|
||||
@@ -323,7 +316,7 @@ class StickerSet(TelegramObject):
|
||||
api_kwargs = {}
|
||||
# These are deprecated fields that TG still returns for backwards compatibility
|
||||
# Let's filter them out to speed up the de-json process
|
||||
for deprecated_field in ("contains_masks", "thumb"):
|
||||
for deprecated_field in ("contains_masks", "thumb", "is_animated", "is_video"):
|
||||
if deprecated_field in data:
|
||||
api_kwargs[deprecated_field] = data.pop(deprecated_field)
|
||||
|
||||
|
||||
@@ -30,7 +30,8 @@ class ForceReply(TelegramObject):
|
||||
Upon receiving a message with this object, Telegram clients will display a reply interface to
|
||||
the user (act as if the user has selected the bot's message and tapped 'Reply'). This can be
|
||||
extremely useful if you want to create user-friendly step-by-step interfaces without having
|
||||
to sacrifice privacy mode.
|
||||
to sacrifice `privacy mode <https://core.telegram.org/bots/features#privacy-mode>`_. Not
|
||||
supported in channels and for messages sent on behalf of a Telegram Business account.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`selective` is equal.
|
||||
|
||||
@@ -41,7 +41,8 @@ class InlineKeyboardButton(TelegramObject):
|
||||
:attr:`web_app` and :attr:`pay` are equal.
|
||||
|
||||
Note:
|
||||
* You must use exactly one of the optional fields. Mind that :attr:`callback_game` is not
|
||||
* Exactly one of the optional fields must be used to specify type of the button.
|
||||
* Mind that :attr:`callback_game` is not
|
||||
working as expected. Putting a game short name in it might, but is not guaranteed to
|
||||
work.
|
||||
* If your bot allows for arbitrary callback data, in keyboards returned in a response
|
||||
@@ -91,6 +92,7 @@ class InlineKeyboardButton(TelegramObject):
|
||||
to the bot when button is pressed, UTF-8
|
||||
:tg-const:`telegram.InlineKeyboardButton.MIN_CALLBACK_DATA`-
|
||||
:tg-const:`telegram.InlineKeyboardButton.MAX_CALLBACK_DATA` bytes.
|
||||
Not supported for messages sent on behalf of a Telegram Business account.
|
||||
If the bot instance allows arbitrary callback data, anything can be passed.
|
||||
|
||||
Tip:
|
||||
@@ -102,35 +104,42 @@ class InlineKeyboardButton(TelegramObject):
|
||||
<https://core.telegram.org/bots/webapps>`_ that will be launched when the user presses
|
||||
the button. The Web App will be able to send an arbitrary message on behalf of the user
|
||||
using the method :meth:`~telegram.Bot.answer_web_app_query`. Available only in
|
||||
private chats between a user and the bot.
|
||||
private chats between a user and the bot. Not supported for messages sent on behalf of
|
||||
a Telegram Business account.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
switch_inline_query (:obj:`str`, optional): If set, pressing the button will prompt the
|
||||
user to select one of their chats, open that chat and insert the bot's username and the
|
||||
specified inline query in the input field. Can be empty, in which case just the bot's
|
||||
username will be inserted. This offers an easy way for users to start using your bot
|
||||
in inline mode when they are currently in a private chat with it. Especially useful
|
||||
when combined with ``switch_pm*`` actions - in this case the user will be automatically
|
||||
returned to the chat they switched from, skipping the chat selection screen.
|
||||
switch_inline_query (:obj:`str`, optional): If set, pressing the button will insert the
|
||||
bot's username and the specified inline query in the current chat's input field. May be
|
||||
empty, in which case only the bot's username will be inserted.
|
||||
|
||||
This offers a quick way for the user to open your bot in inline mode in the same chat -
|
||||
good for selecting something from multiple options. Not supported in channels and for
|
||||
messages sent on behalf of a Telegram Business account.
|
||||
|
||||
Tip:
|
||||
This is similar to the new parameter :paramref:`switch_inline_query_chosen_chat`,
|
||||
but gives no control over which chats can be selected.
|
||||
switch_inline_query_current_chat (:obj:`str`, optional): If set, pressing the button will
|
||||
insert the bot's username and the specified inline query in the current chat's input
|
||||
field. Can be empty, in which case only the bot's username will be inserted. This
|
||||
offers a quick way for the user to open your bot in inline mode in the same chat - good
|
||||
for selecting something from multiple options.
|
||||
prompt the user to select one of their chats of the specified type, open that chat and
|
||||
insert the bot's username and the specified inline query in the input field. Not
|
||||
supported for messages sent on behalf of a Telegram Business account.
|
||||
callback_game (:class:`telegram.CallbackGame`, optional): Description of the game that will
|
||||
be launched when the user presses the button. This type of button **must** always be
|
||||
the **first** button in the first row.
|
||||
pay (:obj:`bool`, optional): Specify :obj:`True`, to send a Pay button. This type of button
|
||||
**must** always be the **first** button in the first row and can only be used in
|
||||
invoice messages.
|
||||
be launched when the user presses the button
|
||||
|
||||
Note:
|
||||
This type of button **must** always be the first button in the first row.
|
||||
pay (:obj:`bool`, optional): Specify :obj:`True`, to send a Pay button.
|
||||
Substrings ``“⭐️”`` and ``“XTR”`` in the buttons's text will be replaced with a
|
||||
Telegram Star icon.
|
||||
|
||||
Note:
|
||||
This type of button **must** always be the first button in the first row and can
|
||||
only be used in invoice messages.
|
||||
switch_inline_query_chosen_chat (:obj:`telegram.SwitchInlineQueryChosenChat`, optional):
|
||||
If set, pressing the button will prompt the user to select one of their chats of the
|
||||
specified type, open that chat and insert the bot's username and the specified inline
|
||||
query in the input field.
|
||||
query in the input field. Not supported for messages sent on behalf of a Telegram
|
||||
Business account.
|
||||
|
||||
.. versionadded:: 20.3
|
||||
|
||||
@@ -159,39 +168,47 @@ class InlineKeyboardButton(TelegramObject):
|
||||
to the bot when button is pressed, UTF-8
|
||||
:tg-const:`telegram.InlineKeyboardButton.MIN_CALLBACK_DATA`-
|
||||
:tg-const:`telegram.InlineKeyboardButton.MAX_CALLBACK_DATA` bytes.
|
||||
Not supported for messages sent on behalf of a Telegram Business account.
|
||||
web_app (:obj:`telegram.WebAppInfo`): Optional. Description of the `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 send an arbitrary message on behalf of the user
|
||||
using the method :meth:`~telegram.Bot.answer_web_app_query`. Available only in
|
||||
private chats between a user and the bot.
|
||||
private chats between a user and the bot. Not supported for messages sent on behalf of
|
||||
a Telegram Business account.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
switch_inline_query (:obj:`str`): Optional. If set, pressing the button will prompt the
|
||||
user to select one of their chats, open that chat and insert the bot's username and the
|
||||
specified inline query in the input field. Can be empty, in which case just the bot's
|
||||
username will be inserted. This offers an easy way for users to start using your bot
|
||||
in inline mode when they are currently in a private chat with it. Especially useful
|
||||
when combined with ``switch_pm*`` actions - in this case the user will be automatically
|
||||
returned to the chat they switched from, skipping the chat selection screen.
|
||||
switch_inline_query (:obj:`str`): Optional. If set, pressing the button will insert the
|
||||
bot's username and the specified inline query in the current chat's input field. May be
|
||||
empty, in which case only the bot's username will be inserted.
|
||||
|
||||
This offers a quick way for the user to open your bot in inline mode in the same chat -
|
||||
good for selecting something from multiple options. Not supported in channels and for
|
||||
messages sent on behalf of a Telegram Business account.
|
||||
|
||||
Tip:
|
||||
This is similar to the new parameter :paramref:`switch_inline_query_chosen_chat`,
|
||||
but gives no control over which chats can be selected.
|
||||
switch_inline_query_current_chat (:obj:`str`): Optional. If set, pressing the button will
|
||||
insert the bot's username and the specified inline query in the current chat's input
|
||||
field. Can be empty, in which case only the bot's username will be inserted. This
|
||||
offers a quick way for the user to open your bot in inline mode in the same chat - good
|
||||
for selecting something from multiple options.
|
||||
prompt the user to select one of their chats of the specified type, open that chat and
|
||||
insert the bot's username and the specified inline query in the input field. Not
|
||||
supported for messages sent on behalf of a Telegram Business account.
|
||||
callback_game (:class:`telegram.CallbackGame`): Optional. Description of the game that will
|
||||
be launched when the user presses the button. This type of button **must** always be
|
||||
the **first** button in the first row.
|
||||
pay (:obj:`bool`): Optional. Specify :obj:`True`, to send a Pay button. This type of button
|
||||
**must** always be the **first** button in the first row and can only be used in
|
||||
invoice messages.
|
||||
be launched when the user presses the button.
|
||||
|
||||
Note:
|
||||
This type of button **must** always be the first button in the first row.
|
||||
pay (:obj:`bool`): Optional. Specify :obj:`True`, to send a Pay button.
|
||||
Substrings ``“⭐️”`` and ``“XTR”`` in the buttons's text will be replaced with a
|
||||
Telegram Star icon.
|
||||
|
||||
Note:
|
||||
This type of button **must** always be the first button in the first row and can
|
||||
only be used in invoice messages.
|
||||
switch_inline_query_chosen_chat (:obj:`telegram.SwitchInlineQueryChosenChat`): Optional.
|
||||
If set, pressing the button will prompt the user to select one of their chats of the
|
||||
specified type, open that chat and insert the bot's username and the specified inline
|
||||
query in the input field.
|
||||
query in the input field. Not supported for messages sent on behalf of a Telegram
|
||||
Business account.
|
||||
|
||||
.. versionadded:: 20.3
|
||||
|
||||
|
||||
@@ -59,6 +59,9 @@ class InlineQueryResultCachedGif(InlineQueryResult):
|
||||
to the message.
|
||||
input_message_content (:class:`telegram.InputMessageContent`, optional): Content of the
|
||||
message to be sent instead of the gif.
|
||||
show_caption_above_media (:obj:`bool`, optional): Pass |show_cap_above_med|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): :tg-const:`telegram.constants.InlineQueryResultType.GIF`.
|
||||
@@ -81,6 +84,9 @@ class InlineQueryResultCachedGif(InlineQueryResult):
|
||||
to the message.
|
||||
input_message_content (:class:`telegram.InputMessageContent`): Optional. Content of the
|
||||
message to be sent instead of the gif.
|
||||
show_caption_above_media (:obj:`bool`): Optional. |show_cap_above_med|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
|
||||
"""
|
||||
|
||||
@@ -91,6 +97,7 @@ class InlineQueryResultCachedGif(InlineQueryResult):
|
||||
"input_message_content",
|
||||
"parse_mode",
|
||||
"reply_markup",
|
||||
"show_caption_above_media",
|
||||
"title",
|
||||
)
|
||||
|
||||
@@ -104,6 +111,7 @@ class InlineQueryResultCachedGif(InlineQueryResult):
|
||||
input_message_content: Optional["InputMessageContent"] = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Optional[Sequence[MessageEntity]] = None,
|
||||
show_caption_above_media: Optional[bool] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
@@ -119,3 +127,4 @@ class InlineQueryResultCachedGif(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.show_caption_above_media: Optional[bool] = show_caption_above_media
|
||||
|
||||
@@ -59,6 +59,9 @@ class InlineQueryResultCachedMpeg4Gif(InlineQueryResult):
|
||||
to the message.
|
||||
input_message_content (:class:`telegram.InputMessageContent`, optional): Content of the
|
||||
message to be sent instead of the MPEG-4 file.
|
||||
show_caption_above_media (:obj:`bool`, optional): Pass |show_cap_above_med|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): :tg-const:`telegram.constants.InlineQueryResultType.MPEG4GIF`.
|
||||
@@ -81,6 +84,9 @@ class InlineQueryResultCachedMpeg4Gif(InlineQueryResult):
|
||||
to the message.
|
||||
input_message_content (:class:`telegram.InputMessageContent`): Optional. Content of the
|
||||
message to be sent instead of the MPEG-4 file.
|
||||
show_caption_above_media (:obj:`bool`): Optional. |show_cap_above_med|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
|
||||
"""
|
||||
|
||||
@@ -91,6 +97,7 @@ class InlineQueryResultCachedMpeg4Gif(InlineQueryResult):
|
||||
"mpeg4_file_id",
|
||||
"parse_mode",
|
||||
"reply_markup",
|
||||
"show_caption_above_media",
|
||||
"title",
|
||||
)
|
||||
|
||||
@@ -104,6 +111,7 @@ class InlineQueryResultCachedMpeg4Gif(InlineQueryResult):
|
||||
input_message_content: Optional["InputMessageContent"] = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Optional[Sequence[MessageEntity]] = None,
|
||||
show_caption_above_media: Optional[bool] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
@@ -119,3 +127,4 @@ class InlineQueryResultCachedMpeg4Gif(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.show_caption_above_media: Optional[bool] = show_caption_above_media
|
||||
|
||||
@@ -60,6 +60,9 @@ class InlineQueryResultCachedPhoto(InlineQueryResult):
|
||||
to the message.
|
||||
input_message_content (:class:`telegram.InputMessageContent`, optional): Content of the
|
||||
message to be sent instead of the photo.
|
||||
show_caption_above_media (:obj:`bool`, optional): Pass |show_cap_above_med|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): :tg-const:`telegram.constants.InlineQueryResultType.PHOTO`.
|
||||
@@ -83,6 +86,9 @@ class InlineQueryResultCachedPhoto(InlineQueryResult):
|
||||
to the message.
|
||||
input_message_content (:class:`telegram.InputMessageContent`): Optional. Content of the
|
||||
message to be sent instead of the photo.
|
||||
show_caption_above_media (:obj:`bool`): Optional. |show_cap_above_med|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
|
||||
"""
|
||||
|
||||
@@ -94,6 +100,7 @@ class InlineQueryResultCachedPhoto(InlineQueryResult):
|
||||
"parse_mode",
|
||||
"photo_file_id",
|
||||
"reply_markup",
|
||||
"show_caption_above_media",
|
||||
"title",
|
||||
)
|
||||
|
||||
@@ -108,6 +115,7 @@ class InlineQueryResultCachedPhoto(InlineQueryResult):
|
||||
input_message_content: Optional["InputMessageContent"] = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Optional[Sequence[MessageEntity]] = None,
|
||||
show_caption_above_media: Optional[bool] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
@@ -124,3 +132,4 @@ class InlineQueryResultCachedPhoto(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.show_caption_above_media: Optional[bool] = show_caption_above_media
|
||||
|
||||
@@ -56,6 +56,9 @@ class InlineQueryResultCachedVideo(InlineQueryResult):
|
||||
to the message.
|
||||
input_message_content (:class:`telegram.InputMessageContent`, optional): Content of the
|
||||
message to be sent instead of the video.
|
||||
show_caption_above_media (:obj:`bool`, optional): Pass |show_cap_above_med|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): :tg-const:`telegram.constants.InlineQueryResultType.VIDEO`.
|
||||
@@ -79,6 +82,9 @@ class InlineQueryResultCachedVideo(InlineQueryResult):
|
||||
to the message.
|
||||
input_message_content (:class:`telegram.InputMessageContent`): Optional. Content of the
|
||||
message to be sent instead of the video.
|
||||
show_caption_above_media (:obj:`bool`): Optional. |show_cap_above_med|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
|
||||
"""
|
||||
|
||||
@@ -89,6 +95,7 @@ class InlineQueryResultCachedVideo(InlineQueryResult):
|
||||
"input_message_content",
|
||||
"parse_mode",
|
||||
"reply_markup",
|
||||
"show_caption_above_media",
|
||||
"title",
|
||||
"video_file_id",
|
||||
)
|
||||
@@ -104,6 +111,7 @@ class InlineQueryResultCachedVideo(InlineQueryResult):
|
||||
input_message_content: Optional["InputMessageContent"] = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Optional[Sequence[MessageEntity]] = None,
|
||||
show_caption_above_media: Optional[bool] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
@@ -120,3 +128,4 @@ class InlineQueryResultCachedVideo(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.show_caption_above_media: Optional[bool] = show_caption_above_media
|
||||
|
||||
@@ -78,6 +78,9 @@ 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.
|
||||
show_caption_above_media (:obj:`bool`, optional): Pass |show_cap_above_med|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
|
||||
Raises:
|
||||
:class:`ValueError`: If neither :paramref:`thumbnail_url` nor :paramref:`thumb_url` is
|
||||
@@ -115,6 +118,9 @@ 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.
|
||||
show_caption_above_media (:obj:`bool`): Optional. |show_cap_above_med|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
|
||||
"""
|
||||
|
||||
@@ -128,6 +134,7 @@ class InlineQueryResultGif(InlineQueryResult):
|
||||
"input_message_content",
|
||||
"parse_mode",
|
||||
"reply_markup",
|
||||
"show_caption_above_media",
|
||||
"thumbnail_mime_type",
|
||||
"thumbnail_url",
|
||||
"title",
|
||||
@@ -148,6 +155,7 @@ class InlineQueryResultGif(InlineQueryResult):
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Optional[Sequence[MessageEntity]] = None,
|
||||
thumbnail_mime_type: Optional[str] = None,
|
||||
show_caption_above_media: Optional[bool] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
@@ -168,3 +176,4 @@ class InlineQueryResultGif(InlineQueryResult):
|
||||
self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup
|
||||
self.input_message_content: Optional[InputMessageContent] = input_message_content
|
||||
self.thumbnail_mime_type: Optional[str] = thumbnail_mime_type
|
||||
self.show_caption_above_media: Optional[bool] = show_caption_above_media
|
||||
|
||||
@@ -89,7 +89,9 @@ class InlineQueryResultLocation(InlineQueryResult):
|
||||
live_period (:obj:`int`): Optional. Period in seconds for which the location will be
|
||||
updated, should be between
|
||||
:tg-const:`telegram.InlineQueryResultLocation.MIN_LIVE_PERIOD` and
|
||||
:tg-const:`telegram.InlineQueryResultLocation.MAX_LIVE_PERIOD`.
|
||||
:tg-const:`telegram.InlineQueryResultLocation.MAX_LIVE_PERIOD` or
|
||||
:tg-const:`telegram.constants.LocationLimit.LIVE_PERIOD_FOREVER` for live
|
||||
locations that can be edited indefinitely.
|
||||
heading (:obj:`int`): Optional. For live locations, a direction in which the user is
|
||||
moving, in degrees. Must be between
|
||||
:tg-const:`telegram.InlineQueryResultLocation.MIN_HEADING` and
|
||||
|
||||
@@ -80,7 +80,9 @@ class InlineQueryResultMpeg4Gif(InlineQueryResult):
|
||||
to the message.
|
||||
input_message_content (:class:`telegram.InputMessageContent`, optional): Content of the
|
||||
message to be sent instead of the video animation.
|
||||
show_caption_above_media (:obj:`bool`, optional): Pass |show_cap_above_med|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
Raises:
|
||||
:class:`ValueError`: If neither :paramref:`thumbnail_url` nor :paramref:`thumb_url` is
|
||||
supplied or if both are supplied and are not equal.
|
||||
@@ -118,7 +120,9 @@ class InlineQueryResultMpeg4Gif(InlineQueryResult):
|
||||
to the message.
|
||||
input_message_content (:class:`telegram.InputMessageContent`): Optional. Content of the
|
||||
message to be sent instead of the video animation.
|
||||
show_caption_above_media (:obj:`bool`): Optional. |show_cap_above_med|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
"""
|
||||
|
||||
__slots__ = (
|
||||
@@ -131,6 +135,7 @@ class InlineQueryResultMpeg4Gif(InlineQueryResult):
|
||||
"mpeg4_width",
|
||||
"parse_mode",
|
||||
"reply_markup",
|
||||
"show_caption_above_media",
|
||||
"thumbnail_mime_type",
|
||||
"thumbnail_url",
|
||||
"title",
|
||||
@@ -151,6 +156,7 @@ class InlineQueryResultMpeg4Gif(InlineQueryResult):
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Optional[Sequence[MessageEntity]] = None,
|
||||
thumbnail_mime_type: Optional[str] = None,
|
||||
show_caption_above_media: Optional[bool] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
@@ -171,3 +177,4 @@ class InlineQueryResultMpeg4Gif(InlineQueryResult):
|
||||
self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup
|
||||
self.input_message_content: Optional[InputMessageContent] = input_message_content
|
||||
self.thumbnail_mime_type: Optional[str] = thumbnail_mime_type
|
||||
self.show_caption_above_media: Optional[bool] = show_caption_above_media
|
||||
|
||||
@@ -74,6 +74,9 @@ class InlineQueryResultPhoto(InlineQueryResult):
|
||||
to the message.
|
||||
input_message_content (:class:`telegram.InputMessageContent`, optional): Content of the
|
||||
message to be sent instead of the photo.
|
||||
show_caption_above_media (:obj:`bool`, optional): Pass |show_cap_above_med|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
|
||||
Raises:
|
||||
:class:`ValueError`: If neither :paramref:`thumbnail_url` nor :paramref:`thumb_url` is
|
||||
@@ -105,6 +108,9 @@ class InlineQueryResultPhoto(InlineQueryResult):
|
||||
to the message.
|
||||
input_message_content (:class:`telegram.InputMessageContent`): Optional. Content of the
|
||||
message to be sent instead of the photo.
|
||||
show_caption_above_media (:obj:`bool`): Optional. |show_cap_above_med|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
|
||||
"""
|
||||
|
||||
@@ -118,6 +124,7 @@ class InlineQueryResultPhoto(InlineQueryResult):
|
||||
"photo_url",
|
||||
"photo_width",
|
||||
"reply_markup",
|
||||
"show_caption_above_media",
|
||||
"thumbnail_url",
|
||||
"title",
|
||||
)
|
||||
@@ -136,6 +143,7 @@ class InlineQueryResultPhoto(InlineQueryResult):
|
||||
input_message_content: Optional["InputMessageContent"] = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Optional[Sequence[MessageEntity]] = None,
|
||||
show_caption_above_media: Optional[bool] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
@@ -155,3 +163,4 @@ 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
|
||||
self.show_caption_above_media: Optional[bool] = show_caption_above_media
|
||||
|
||||
@@ -88,6 +88,9 @@ 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).
|
||||
show_caption_above_media (:obj:`bool`, optional): Pass |show_cap_above_med|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
|
||||
Raises:
|
||||
:class:`ValueError`: If neither :paramref:`thumbnail_url` nor :paramref:`thumb_url` is
|
||||
@@ -127,6 +130,9 @@ 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).
|
||||
show_caption_above_media (:obj:`bool`): Optional. |show_cap_above_med|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
|
||||
"""
|
||||
|
||||
@@ -138,6 +144,7 @@ class InlineQueryResultVideo(InlineQueryResult):
|
||||
"mime_type",
|
||||
"parse_mode",
|
||||
"reply_markup",
|
||||
"show_caption_above_media",
|
||||
"thumbnail_url",
|
||||
"title",
|
||||
"video_duration",
|
||||
@@ -162,6 +169,7 @@ class InlineQueryResultVideo(InlineQueryResult):
|
||||
input_message_content: Optional["InputMessageContent"] = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Optional[Sequence[MessageEntity]] = None,
|
||||
show_caption_above_media: Optional[bool] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
@@ -183,3 +191,4 @@ class InlineQueryResultVideo(InlineQueryResult):
|
||||
self.description: Optional[str] = description
|
||||
self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup
|
||||
self.input_message_content: Optional[InputMessageContent] = input_message_content
|
||||
self.show_caption_above_media: Optional[bool] = show_caption_above_media
|
||||
|
||||
@@ -49,12 +49,18 @@ class InputInvoiceMessageContent(InputMessageContent):
|
||||
:tg-const:`telegram.Invoice.MAX_PAYLOAD_LENGTH` bytes. This will not be displayed
|
||||
to the user, use for your internal processes.
|
||||
provider_token (:obj:`str`): Payment provider token, obtained via
|
||||
`@Botfather <https://t.me/Botfather>`_.
|
||||
`@Botfather <https://t.me/Botfather>`_. Pass an empty string for payments in
|
||||
|tg_stars|.
|
||||
|
||||
.. deprecated:: 21.3
|
||||
As of Bot API 7.4, this parameter is now optional and future versions of the
|
||||
library will make it optional as well.
|
||||
currency (:obj:`str`): Three-letter ISO 4217 currency code, see more on
|
||||
`currencies <https://core.telegram.org/bots/payments#supported-currencies>`_
|
||||
`currencies <https://core.telegram.org/bots/payments#supported-currencies>`_.
|
||||
Pass ``XTR`` for payments in |tg_stars|.
|
||||
prices (Sequence[:class:`telegram.LabeledPrice`]): Price breakdown, a list of
|
||||
components (e.g. product price, tax, discount, delivery cost, delivery tax, bonus,
|
||||
etc.)
|
||||
etc.). Must contain exactly one item for payments in |tg_stars|.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceclassargs|
|
||||
@@ -64,7 +70,8 @@ class InputInvoiceMessageContent(InputMessageContent):
|
||||
maximum tip of US$ 1.45 pass ``max_tip_amount = 145``. See the ``exp`` parameter in
|
||||
`currencies.json <https://core.telegram.org/bots/payments/currencies.json>`_, it
|
||||
shows the number of digits past the decimal point for each currency (2 for the majority
|
||||
of currencies). Defaults to ``0``.
|
||||
of currencies). Defaults to ``0``. Defaults to ``0``. Not supported for payments in
|
||||
|tg_stars|.
|
||||
suggested_tip_amounts (Sequence[:obj:`int`], optional): An array of suggested
|
||||
amounts of tip in the *smallest* units of the currency (integer, **not** float/double).
|
||||
At most 4 suggested tip amounts can be specified. The suggested tip amounts must be
|
||||
@@ -85,20 +92,20 @@ class InputInvoiceMessageContent(InputMessageContent):
|
||||
photo_size (:obj:`int`, optional): Photo size.
|
||||
photo_width (:obj:`int`, optional): Photo width.
|
||||
photo_height (:obj:`int`, optional): Photo height.
|
||||
need_name (:obj:`bool`, optional): Pass :obj:`True`, if you require the user's full name to
|
||||
complete the order.
|
||||
need_name (:obj:`bool`, optional): Pass :obj:`True`, if you require the user's full
|
||||
name to complete the order. Ignored for payments in |tg_stars|.
|
||||
need_phone_number (:obj:`bool`, optional): Pass :obj:`True`, if you require the user's
|
||||
phone number to complete the order
|
||||
phone number to complete the order. Ignored for payments in |tg_stars|.
|
||||
need_email (:obj:`bool`, optional): Pass :obj:`True`, if you require the user's email
|
||||
address to complete the order.
|
||||
need_shipping_address (:obj:`bool`, optional): Pass :obj:`True`, if you require the user's
|
||||
shipping address to complete the order
|
||||
send_phone_number_to_provider (:obj:`bool`, optional): Pass :obj:`True`, if user's phone
|
||||
number should be sent to provider.
|
||||
send_email_to_provider (:obj:`bool`, optional): Pass :obj:`True`, if user's email address
|
||||
should be sent to provider.
|
||||
is_flexible (:obj:`bool`, optional): Pass :obj:`True`, if the final price depends on the
|
||||
shipping method.
|
||||
address to complete the order. Ignored for payments in |tg_stars|.
|
||||
need_shipping_address (:obj:`bool`, optional): Pass :obj:`True`, if you require the
|
||||
user's shipping address to complete the order. Ignored for payments in |tg_stars|
|
||||
send_phone_number_to_provider (:obj:`bool`, optional): Pass :obj:`True`, if user's
|
||||
phone number should be sent to provider. Ignored for payments in |tg_stars|.
|
||||
send_email_to_provider (:obj:`bool`, optional): Pass :obj:`True`, if user's email
|
||||
address should be sent to provider. Ignored for payments in |tg_stars|.
|
||||
is_flexible (:obj:`bool`, optional): Pass :obj:`True`, if the final price depends on
|
||||
the shipping method. Ignored for payments in |tg_stars|.
|
||||
|
||||
Attributes:
|
||||
title (:obj:`str`): Product name. :tg-const:`telegram.Invoice.MIN_TITLE_LENGTH`-
|
||||
@@ -111,12 +118,14 @@ class InputInvoiceMessageContent(InputMessageContent):
|
||||
:tg-const:`telegram.Invoice.MAX_PAYLOAD_LENGTH` bytes. This will not be displayed
|
||||
to the user, use for your internal processes.
|
||||
provider_token (:obj:`str`): Payment provider token, obtained via
|
||||
`@Botfather <https://t.me/Botfather>`_.
|
||||
`@Botfather <https://t.me/Botfather>`_. Pass an empty string for payments in `Telegram
|
||||
Stars <https://t.me/BotNews/90>`_.
|
||||
currency (:obj:`str`): Three-letter ISO 4217 currency code, see more on
|
||||
`currencies <https://core.telegram.org/bots/payments#supported-currencies>`_
|
||||
`currencies <https://core.telegram.org/bots/payments#supported-currencies>`_.
|
||||
Pass ``XTR`` for payments in |tg_stars|.
|
||||
prices (Tuple[:class:`telegram.LabeledPrice`]): Price breakdown, a list of
|
||||
components (e.g. product price, tax, discount, delivery cost, delivery tax, bonus,
|
||||
etc.)
|
||||
etc.). Must contain exactly one item for payments in |tg_stars|.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|tupleclassattrs|
|
||||
@@ -126,7 +135,7 @@ class InputInvoiceMessageContent(InputMessageContent):
|
||||
maximum tip of US$ 1.45 ``max_tip_amount`` is ``145``. See the ``exp`` parameter in
|
||||
`currencies.json <https://core.telegram.org/bots/payments/currencies.json>`_, it
|
||||
shows the number of digits past the decimal point for each currency (2 for the majority
|
||||
of currencies). Defaults to ``0``.
|
||||
of currencies). Defaults to ``0``. Not supported for payments in |tg_stars|.
|
||||
suggested_tip_amounts (Tuple[:obj:`int`]): Optional. An array of suggested
|
||||
amounts of tip in the *smallest* units of the currency (integer, **not** float/double).
|
||||
At most 4 suggested tip amounts can be specified. The suggested tip amounts must be
|
||||
@@ -146,19 +155,19 @@ class InputInvoiceMessageContent(InputMessageContent):
|
||||
photo_width (:obj:`int`): Optional. Photo width.
|
||||
photo_height (:obj:`int`): Optional. Photo height.
|
||||
need_name (:obj:`bool`): Optional. Pass :obj:`True`, if you require the user's full name to
|
||||
complete the order.
|
||||
complete the order. Ignored for payments in |tg_stars|.
|
||||
need_phone_number (:obj:`bool`): Optional. Pass :obj:`True`, if you require the user's
|
||||
phone number to complete the order
|
||||
phone number to complete the order. Ignored for payments in |tg_stars|.
|
||||
need_email (:obj:`bool`): Optional. Pass :obj:`True`, if you require the user's email
|
||||
address to complete the order.
|
||||
address to complete the order. Ignored for payments in |tg_stars|.
|
||||
need_shipping_address (:obj:`bool`): Optional. Pass :obj:`True`, if you require the user's
|
||||
shipping address to complete the order
|
||||
shipping address to complete the order. Ignored for payments in |tg_stars|.
|
||||
send_phone_number_to_provider (:obj:`bool`): Optional. Pass :obj:`True`, if user's phone
|
||||
number should be sent to provider.
|
||||
number should be sent to provider. Ignored for payments in |tg_stars|.
|
||||
send_email_to_provider (:obj:`bool`): Optional. Pass :obj:`True`, if user's email address
|
||||
should be sent to provider.
|
||||
should be sent to provider. Ignored for payments in |tg_stars|.
|
||||
is_flexible (:obj:`bool`): Optional. Pass :obj:`True`, if the final price depends on the
|
||||
shipping method.
|
||||
shipping method. Ignored for payments in |tg_stars|.
|
||||
|
||||
"""
|
||||
|
||||
@@ -190,7 +199,7 @@ class InputInvoiceMessageContent(InputMessageContent):
|
||||
title: str,
|
||||
description: str,
|
||||
payload: str,
|
||||
provider_token: str,
|
||||
provider_token: Optional[str], # This arg is now optional since Bot API 7.4
|
||||
currency: str,
|
||||
prices: Sequence[LabeledPrice],
|
||||
max_tip_amount: Optional[int] = None,
|
||||
@@ -216,7 +225,7 @@ class InputInvoiceMessageContent(InputMessageContent):
|
||||
self.title: str = title
|
||||
self.description: str = description
|
||||
self.payload: str = payload
|
||||
self.provider_token: str = provider_token
|
||||
self.provider_token: Optional[str] = provider_token
|
||||
self.currency: str = currency
|
||||
self.prices: Tuple[LabeledPrice, ...] = parse_sequence_arg(prices)
|
||||
# Optionals
|
||||
|
||||
@@ -42,7 +42,9 @@ class InputLocationMessageContent(InputMessageContent):
|
||||
live_period (:obj:`int`, optional): Period in seconds for which the location will be
|
||||
updated, should be between
|
||||
:tg-const:`telegram.InputLocationMessageContent.MIN_LIVE_PERIOD` and
|
||||
:tg-const:`telegram.InputLocationMessageContent.MAX_LIVE_PERIOD`.
|
||||
:tg-const:`telegram.InputLocationMessageContent.MAX_LIVE_PERIOD` or
|
||||
:tg-const:`telegram.constants.LocationLimit.LIVE_PERIOD_FOREVER` for live
|
||||
locations that can be edited indefinitely.
|
||||
heading (:obj:`int`, optional): For live locations, a direction in which the user is
|
||||
moving, in degrees. Must be between
|
||||
:tg-const:`telegram.InputLocationMessageContent.MIN_HEADING` and
|
||||
|
||||
@@ -32,7 +32,8 @@ if TYPE_CHECKING:
|
||||
|
||||
class KeyboardButton(TelegramObject):
|
||||
"""
|
||||
This object represents one button of the reply keyboard. For simple text buttons, :obj:`str`
|
||||
This object represents one button of the reply keyboard. At most one of the optional fields
|
||||
must be used to specify type of the button. For simple text buttons, :obj:`str`
|
||||
can be used instead of this object to specify text of the button.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains two objects to request chats/users."""
|
||||
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from telegram._chatadministratorrights import ChatAdministratorRights
|
||||
@@ -56,6 +57,16 @@ class KeyboardButtonRequestUsers(TelegramObject):
|
||||
.
|
||||
|
||||
.. versionadded:: 20.8
|
||||
request_name (:obj:`bool`, optional): Pass :obj:`True` to request the users' first and last
|
||||
name.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
request_username (:obj:`bool`, optional): Pass :obj:`True` to request the users' username.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
request_photo (:obj:`bool`, optional): Pass :obj:`True` to request the users' photo.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
|
||||
Attributes:
|
||||
request_id (:obj:`int`): Identifier of the request.
|
||||
@@ -71,11 +82,25 @@ class KeyboardButtonRequestUsers(TelegramObject):
|
||||
.
|
||||
|
||||
.. versionadded:: 20.8
|
||||
request_name (:obj:`bool`): Optional. Pass :obj:`True` to request the users' first and last
|
||||
name.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
request_username (:obj:`bool`): Optional. Pass :obj:`True` to request the users' username.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
request_photo (:obj:`bool`): Optional. Pass :obj:`True` to request the users' photo.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = (
|
||||
"max_quantity",
|
||||
"request_id",
|
||||
"request_name",
|
||||
"request_photo",
|
||||
"request_username",
|
||||
"user_is_bot",
|
||||
"user_is_premium",
|
||||
)
|
||||
@@ -86,6 +111,9 @@ class KeyboardButtonRequestUsers(TelegramObject):
|
||||
user_is_bot: Optional[bool] = None,
|
||||
user_is_premium: Optional[bool] = None,
|
||||
max_quantity: Optional[int] = None,
|
||||
request_name: Optional[bool] = None,
|
||||
request_username: Optional[bool] = None,
|
||||
request_photo: Optional[bool] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
@@ -97,6 +125,9 @@ class KeyboardButtonRequestUsers(TelegramObject):
|
||||
self.user_is_bot: Optional[bool] = user_is_bot
|
||||
self.user_is_premium: Optional[bool] = user_is_premium
|
||||
self.max_quantity: Optional[int] = max_quantity
|
||||
self.request_name: Optional[bool] = request_name
|
||||
self.request_username: Optional[bool] = request_username
|
||||
self.request_photo: Optional[bool] = request_photo
|
||||
|
||||
self._id_attrs = (self.request_id,)
|
||||
|
||||
@@ -138,6 +169,15 @@ class KeyboardButtonRequestChat(TelegramObject):
|
||||
applied.
|
||||
bot_is_member (:obj:`bool`, optional): Pass :obj:`True` to request a chat with the bot
|
||||
as a member. Otherwise, no additional restrictions are applied.
|
||||
request_title (:obj:`bool`, optional): Pass :obj:`True` to request the chat's title.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
request_username (:obj:`bool`, optional): Pass :obj:`True` to request the chat's username.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
request_photo (:obj:`bool`, optional): Pass :obj:`True` to request the chat's photo.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
Attributes:
|
||||
request_id (:obj:`int`): Identifier of the request.
|
||||
chat_is_channel (:obj:`bool`): Pass :obj:`True` to request a channel chat, pass
|
||||
@@ -145,7 +185,7 @@ class KeyboardButtonRequestChat(TelegramObject):
|
||||
chat_is_forum (:obj:`bool`): Optional. Pass :obj:`True` to request a forum supergroup, pass
|
||||
:obj:`False` to request a non-forum chat. If not specified, no additional
|
||||
restrictions are applied.
|
||||
chat_has_username (:obj:`bool`, optional): Pass :obj:`True` to request a supergroup or a
|
||||
chat_has_username (:obj:`bool`): Optional. Pass :obj:`True` to request a supergroup or a
|
||||
channel with a username, pass :obj:`False` to request a chat without a username. If
|
||||
not specified, no additional restrictions are applied.
|
||||
chat_is_created (:obj:`bool`) Optional. Pass :obj:`True` to request a chat owned by the
|
||||
@@ -159,6 +199,15 @@ class KeyboardButtonRequestChat(TelegramObject):
|
||||
applied.
|
||||
bot_is_member (:obj:`bool`) Optional. Pass :obj:`True` to request a chat with the bot
|
||||
as a member. Otherwise, no additional restrictions are applied.
|
||||
request_title (:obj:`bool`): Optional. Pass :obj:`True` to request the chat's title.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
request_username (:obj:`bool`): Optional. Pass :obj:`True` to request the chat's username.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
request_photo (:obj:`bool`): Optional. Pass :obj:`True` to request the chat's photo.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
"""
|
||||
|
||||
__slots__ = (
|
||||
@@ -169,6 +218,9 @@ class KeyboardButtonRequestChat(TelegramObject):
|
||||
"chat_is_created",
|
||||
"chat_is_forum",
|
||||
"request_id",
|
||||
"request_photo",
|
||||
"request_title",
|
||||
"request_username",
|
||||
"user_administrator_rights",
|
||||
)
|
||||
|
||||
@@ -182,6 +234,9 @@ class KeyboardButtonRequestChat(TelegramObject):
|
||||
user_administrator_rights: Optional[ChatAdministratorRights] = None,
|
||||
bot_administrator_rights: Optional[ChatAdministratorRights] = None,
|
||||
bot_is_member: Optional[bool] = None,
|
||||
request_title: Optional[bool] = None,
|
||||
request_username: Optional[bool] = None,
|
||||
request_photo: Optional[bool] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
@@ -199,6 +254,9 @@ class KeyboardButtonRequestChat(TelegramObject):
|
||||
)
|
||||
self.bot_administrator_rights: Optional[ChatAdministratorRights] = bot_administrator_rights
|
||||
self.bot_is_member: Optional[bool] = bot_is_member
|
||||
self.request_title: Optional[bool] = request_title
|
||||
self.request_username: Optional[bool] = request_username
|
||||
self.request_photo: Optional[bool] = request_photo
|
||||
|
||||
self._id_attrs = (self.request_id,)
|
||||
|
||||
|
||||
+458
-80
File diff suppressed because it is too large
Load Diff
+40
-35
@@ -140,50 +140,55 @@ class MessageEntity(TelegramObject):
|
||||
|
||||
return super().de_json(data=data, bot=bot)
|
||||
|
||||
MENTION: Final[str] = constants.MessageEntityType.MENTION
|
||||
""":const:`telegram.constants.MessageEntityType.MENTION`"""
|
||||
HASHTAG: Final[str] = constants.MessageEntityType.HASHTAG
|
||||
""":const:`telegram.constants.MessageEntityType.HASHTAG`"""
|
||||
CASHTAG: Final[str] = constants.MessageEntityType.CASHTAG
|
||||
""":const:`telegram.constants.MessageEntityType.CASHTAG`"""
|
||||
PHONE_NUMBER: Final[str] = constants.MessageEntityType.PHONE_NUMBER
|
||||
""":const:`telegram.constants.MessageEntityType.PHONE_NUMBER`"""
|
||||
BOT_COMMAND: Final[str] = constants.MessageEntityType.BOT_COMMAND
|
||||
""":const:`telegram.constants.MessageEntityType.BOT_COMMAND`"""
|
||||
URL: Final[str] = constants.MessageEntityType.URL
|
||||
""":const:`telegram.constants.MessageEntityType.URL`"""
|
||||
EMAIL: Final[str] = constants.MessageEntityType.EMAIL
|
||||
""":const:`telegram.constants.MessageEntityType.EMAIL`"""
|
||||
ALL_TYPES: Final[List[str]] = list(constants.MessageEntityType)
|
||||
"""List[:obj:`str`]: A list of all available message entity types."""
|
||||
BLOCKQUOTE: Final[str] = constants.MessageEntityType.BLOCKQUOTE
|
||||
""":const:`telegram.constants.MessageEntityType.BLOCKQUOTE`
|
||||
|
||||
.. versionadded:: 20.8
|
||||
"""
|
||||
BOLD: Final[str] = constants.MessageEntityType.BOLD
|
||||
""":const:`telegram.constants.MessageEntityType.BOLD`"""
|
||||
ITALIC: Final[str] = constants.MessageEntityType.ITALIC
|
||||
""":const:`telegram.constants.MessageEntityType.ITALIC`"""
|
||||
BOT_COMMAND: Final[str] = constants.MessageEntityType.BOT_COMMAND
|
||||
""":const:`telegram.constants.MessageEntityType.BOT_COMMAND`"""
|
||||
CASHTAG: Final[str] = constants.MessageEntityType.CASHTAG
|
||||
""":const:`telegram.constants.MessageEntityType.CASHTAG`"""
|
||||
CODE: Final[str] = constants.MessageEntityType.CODE
|
||||
""":const:`telegram.constants.MessageEntityType.CODE`"""
|
||||
CUSTOM_EMOJI: Final[str] = constants.MessageEntityType.CUSTOM_EMOJI
|
||||
""":const:`telegram.constants.MessageEntityType.CUSTOM_EMOJI`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
EMAIL: Final[str] = constants.MessageEntityType.EMAIL
|
||||
""":const:`telegram.constants.MessageEntityType.EMAIL`"""
|
||||
EXPANDABLE_BLOCKQUOTE: Final[str] = constants.MessageEntityType.EXPANDABLE_BLOCKQUOTE
|
||||
""":const:`telegram.constants.MessageEntityType.EXPANDABLE_BLOCKQUOTE`
|
||||
|
||||
.. versionadded:: 21.3
|
||||
"""
|
||||
HASHTAG: Final[str] = constants.MessageEntityType.HASHTAG
|
||||
""":const:`telegram.constants.MessageEntityType.HASHTAG`"""
|
||||
ITALIC: Final[str] = constants.MessageEntityType.ITALIC
|
||||
""":const:`telegram.constants.MessageEntityType.ITALIC`"""
|
||||
MENTION: Final[str] = constants.MessageEntityType.MENTION
|
||||
""":const:`telegram.constants.MessageEntityType.MENTION`"""
|
||||
PHONE_NUMBER: Final[str] = constants.MessageEntityType.PHONE_NUMBER
|
||||
""":const:`telegram.constants.MessageEntityType.PHONE_NUMBER`"""
|
||||
PRE: Final[str] = constants.MessageEntityType.PRE
|
||||
""":const:`telegram.constants.MessageEntityType.PRE`"""
|
||||
SPOILER: Final[str] = constants.MessageEntityType.SPOILER
|
||||
""":const:`telegram.constants.MessageEntityType.SPOILER`
|
||||
|
||||
.. versionadded:: 13.10
|
||||
"""
|
||||
STRIKETHROUGH: Final[str] = constants.MessageEntityType.STRIKETHROUGH
|
||||
""":const:`telegram.constants.MessageEntityType.STRIKETHROUGH`"""
|
||||
TEXT_LINK: Final[str] = constants.MessageEntityType.TEXT_LINK
|
||||
""":const:`telegram.constants.MessageEntityType.TEXT_LINK`"""
|
||||
TEXT_MENTION: Final[str] = constants.MessageEntityType.TEXT_MENTION
|
||||
""":const:`telegram.constants.MessageEntityType.TEXT_MENTION`"""
|
||||
UNDERLINE: Final[str] = constants.MessageEntityType.UNDERLINE
|
||||
""":const:`telegram.constants.MessageEntityType.UNDERLINE`"""
|
||||
STRIKETHROUGH: Final[str] = constants.MessageEntityType.STRIKETHROUGH
|
||||
""":const:`telegram.constants.MessageEntityType.STRIKETHROUGH`"""
|
||||
SPOILER: Final[str] = constants.MessageEntityType.SPOILER
|
||||
""":const:`telegram.constants.MessageEntityType.SPOILER`
|
||||
|
||||
.. versionadded:: 13.10
|
||||
"""
|
||||
CUSTOM_EMOJI: Final[str] = constants.MessageEntityType.CUSTOM_EMOJI
|
||||
""":const:`telegram.constants.MessageEntityType.CUSTOM_EMOJI`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
BLOCKQUOTE: Final[str] = constants.MessageEntityType.BLOCKQUOTE
|
||||
""":const:`telegram.constants.MessageEntityType.BLOCKQUOTE`
|
||||
|
||||
.. versionadded:: 20.8
|
||||
"""
|
||||
ALL_TYPES: Final[List[str]] = list(constants.MessageEntityType)
|
||||
"""List[:obj:`str`]: A list of all available message entity types."""
|
||||
URL: Final[str] = constants.MessageEntityType.URL
|
||||
""":const:`telegram.constants.MessageEntityType.URL`"""
|
||||
|
||||
@@ -153,15 +153,15 @@ class EncryptedCredentials(TelegramObject):
|
||||
|
||||
self._id_attrs = (self.data, self.hash, self.secret)
|
||||
|
||||
self._decrypted_secret: Optional[str] = None
|
||||
self._decrypted_secret: Optional[bytes] = None
|
||||
self._decrypted_data: Optional[Credentials] = None
|
||||
|
||||
self._freeze()
|
||||
|
||||
@property
|
||||
def decrypted_secret(self) -> str:
|
||||
def decrypted_secret(self) -> bytes:
|
||||
"""
|
||||
:obj:`str`: Lazily decrypt and return secret.
|
||||
:obj:`bytes`: Lazily decrypt and return secret.
|
||||
|
||||
Raises:
|
||||
telegram.error.PassportDecryptionError: Decryption failed. Usually due to bad
|
||||
|
||||
@@ -60,8 +60,8 @@ class EncryptedPassportElement(TelegramObject):
|
||||
email (:obj:`str`, optional): User's verified email address; available only for "email"
|
||||
type.
|
||||
files (Sequence[:class:`telegram.PassportFile`], optional): Array of encrypted/decrypted
|
||||
files with documents provided by the user; available only for "utility_bill",
|
||||
"bank_statement", "rental_agreement", "passport_registration" and
|
||||
files with documents provided by the user; available only for "utility_bill",
|
||||
"bank_statement", "rental_agreement", "passport_registration" and
|
||||
"temporary_registration" types.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
@@ -74,12 +74,12 @@ class EncryptedPassportElement(TelegramObject):
|
||||
reverse side of the document, provided by the user; Available only for
|
||||
"driver_license" and "identity_card".
|
||||
selfie (:class:`telegram.PassportFile`, optional): Encrypted/decrypted file with the
|
||||
selfie of the user holding a document, provided by the user; available if requested for
|
||||
selfie of the user holding a document, provided by the user; available if requested for
|
||||
"passport", "driver_license", "identity_card" and "internal_passport".
|
||||
translation (Sequence[:class:`telegram.PassportFile`], optional): Array of
|
||||
encrypted/decrypted files with translated versions of documents provided by the user;
|
||||
available if requested requested for "passport", "driver_license", "identity_card",
|
||||
"internal_passport", "utility_bill", "bank_statement", "rental_agreement",
|
||||
encrypted/decrypted files with translated versions of documents provided by the user;
|
||||
available if requested requested for "passport", "driver_license", "identity_card",
|
||||
"internal_passport", "utility_bill", "bank_statement", "rental_agreement",
|
||||
"passport_registration" and "temporary_registration" types.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
@@ -101,8 +101,8 @@ class EncryptedPassportElement(TelegramObject):
|
||||
email (:obj:`str`): Optional. User's verified email address; available only for "email"
|
||||
type.
|
||||
files (Tuple[:class:`telegram.PassportFile`]): Optional. Array of encrypted/decrypted
|
||||
files with documents provided by the user; available only for "utility_bill",
|
||||
"bank_statement", "rental_agreement", "passport_registration" and
|
||||
files with documents provided by the user; available only for "utility_bill",
|
||||
"bank_statement", "rental_agreement", "passport_registration" and
|
||||
"temporary_registration" types.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
@@ -157,7 +157,10 @@ class EncryptedPassportElement(TelegramObject):
|
||||
reverse_side: Optional[PassportFile] = None,
|
||||
selfie: Optional[PassportFile] = None,
|
||||
translation: Optional[Sequence[PassportFile]] = None,
|
||||
credentials: Optional["Credentials"] = None, # pylint: disable=unused-argument
|
||||
# TODO: Remove the credentials argument in 22.0 or later
|
||||
credentials: Optional[ # pylint: disable=unused-argument # noqa: ARG002
|
||||
"Credentials"
|
||||
] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
|
||||
@@ -210,9 +210,11 @@ class PassportElementErrorFiles(PassportElementError):
|
||||
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,
|
||||
PTBDeprecationWarning(
|
||||
"20.6",
|
||||
"The attribute `file_hashes` will return a tuple instead of a list in future major"
|
||||
" versions.",
|
||||
),
|
||||
stacklevel=2,
|
||||
)
|
||||
return self._file_hashes
|
||||
@@ -427,10 +429,12 @@ class PassportElementErrorTranslationFiles(PassportElementError):
|
||||
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,
|
||||
PTBDeprecationWarning(
|
||||
"20.6",
|
||||
"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",
|
||||
),
|
||||
stacklevel=2,
|
||||
)
|
||||
return self._file_hashes
|
||||
|
||||
@@ -107,9 +107,11 @@ class PassportFile(TelegramObject):
|
||||
This attribute will return a datetime instead of a integer in future major versions.
|
||||
"""
|
||||
warn(
|
||||
"The attribute `file_date` will return a datetime instead of an integer in future"
|
||||
" major versions.",
|
||||
PTBDeprecationWarning,
|
||||
PTBDeprecationWarning(
|
||||
"20.6",
|
||||
"The attribute `file_date` will return a datetime instead of an integer in future"
|
||||
" major versions.",
|
||||
),
|
||||
stacklevel=2,
|
||||
)
|
||||
return self._file_date
|
||||
@@ -203,5 +205,6 @@ class PassportFile(TelegramObject):
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
file.set_credentials(self._credentials)
|
||||
if self._credentials:
|
||||
file.set_credentials(self._credentials)
|
||||
return file
|
||||
|
||||
@@ -37,7 +37,8 @@ class Invoice(TelegramObject):
|
||||
description (:obj:`str`): Product description.
|
||||
start_parameter (:obj:`str`): Unique bot deep-linking parameter that can be used to
|
||||
generate this invoice.
|
||||
currency (:obj:`str`): Three-letter ISO 4217 currency code.
|
||||
currency (:obj:`str`): Three-letter ISO 4217 currency code, or ``XTR`` for payments in
|
||||
|tg_stars|.
|
||||
total_amount (:obj:`int`): Total price in the smallest units of the currency (integer, not
|
||||
float/double). For example, for a price of US$ 1.45 pass ``amount = 145``. See the
|
||||
``exp`` parameter in
|
||||
@@ -50,7 +51,8 @@ class Invoice(TelegramObject):
|
||||
description (:obj:`str`): Product description.
|
||||
start_parameter (:obj:`str`): Unique bot deep-linking parameter that can be used to
|
||||
generate this invoice.
|
||||
currency (:obj:`str`): Three-letter ISO 4217 currency code.
|
||||
currency (:obj:`str`): Three-letter ISO 4217 currency code, or ``XTR`` for payments in
|
||||
|tg_stars|.
|
||||
total_amount (:obj:`int`): Total price in the smallest units of the currency (integer, not
|
||||
float/double). For example, for a price of US$ 1.45 ``amount`` is ``145``. See the
|
||||
``exp`` parameter in
|
||||
|
||||
@@ -42,7 +42,8 @@ class PreCheckoutQuery(TelegramObject):
|
||||
Args:
|
||||
id (:obj:`str`): Unique query identifier.
|
||||
from_user (:class:`telegram.User`): User who sent the query.
|
||||
currency (:obj:`str`): Three-letter ISO 4217 currency code.
|
||||
currency (:obj:`str`): Three-letter ISO 4217 currency code, or ``XTR`` for payments in
|
||||
|tg_stars|.
|
||||
total_amount (:obj:`int`): Total price in the smallest units of the currency (integer, not
|
||||
float/double). For example, for a price of US$ 1.45 pass ``amount = 145``.
|
||||
See the ``exp`` parameter in
|
||||
@@ -57,7 +58,8 @@ class PreCheckoutQuery(TelegramObject):
|
||||
Attributes:
|
||||
id (:obj:`str`): Unique query identifier.
|
||||
from_user (:class:`telegram.User`): User who sent the query.
|
||||
currency (:obj:`str`): Three-letter ISO 4217 currency code.
|
||||
currency (:obj:`str`): Three-letter ISO 4217 currency code, or ``XTR`` for payments in
|
||||
|tg_stars|.
|
||||
total_amount (:obj:`int`): Total price in the smallest units of the currency (integer, not
|
||||
float/double). For example, for a price of US$ 1.45 ``amount`` is ``145``.
|
||||
See the ``exp`` parameter in
|
||||
|
||||
@@ -36,7 +36,8 @@ class SuccessfulPayment(TelegramObject):
|
||||
:attr:`provider_payment_charge_id` are equal.
|
||||
|
||||
Args:
|
||||
currency (:obj:`str`): Three-letter ISO 4217 currency code.
|
||||
currency (:obj:`str`): Three-letter ISO 4217 currency code, or ``XTR`` for payments in
|
||||
|tg_stars|.
|
||||
total_amount (:obj:`int`): Total price in the smallest units of the currency (integer, not
|
||||
float/double). For example, for a price of US$ 1.45 pass ``amount = 145``.
|
||||
See the ``exp`` parameter in
|
||||
@@ -51,7 +52,8 @@ class SuccessfulPayment(TelegramObject):
|
||||
provider_payment_charge_id (:obj:`str`): Provider payment identifier.
|
||||
|
||||
Attributes:
|
||||
currency (:obj:`str`): Three-letter ISO 4217 currency code.
|
||||
currency (:obj:`str`): Three-letter ISO 4217 currency code, or ``XTR`` for payments in
|
||||
|tg_stars|.
|
||||
total_amount (:obj:`int`): Total price in the smallest units of the currency (integer, not
|
||||
float/double). For example, for a price of US$ 1.45 ``amount`` is ``145``.
|
||||
See the ``exp`` parameter in
|
||||
|
||||
+219
-17
@@ -28,12 +28,80 @@ from telegram._user import User
|
||||
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.types import JSONDict
|
||||
from telegram._utils.defaultvalue import DEFAULT_NONE
|
||||
from telegram._utils.entities import parse_message_entities, parse_message_entity
|
||||
from telegram._utils.types import JSONDict, ODVInput
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import Bot
|
||||
|
||||
|
||||
class InputPollOption(TelegramObject):
|
||||
"""
|
||||
This object contains information about one answer option in a poll to send.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`text` is equal.
|
||||
|
||||
.. versionadded:: 21.2
|
||||
|
||||
Args:
|
||||
text (:obj:`str`): Option text,
|
||||
:tg-const:`telegram.PollOption.MIN_LENGTH`-:tg-const:`telegram.PollOption.MAX_LENGTH`
|
||||
characters.
|
||||
text_parse_mode (:obj:`str`, optional): |parse_mode|
|
||||
Currently, only custom emoji entities are allowed.
|
||||
text_entities (Sequence[:class:`telegram.MessageEntity`], optional): Special entities
|
||||
that appear in the option :paramref:`text`. It can be specified instead of
|
||||
:paramref:`text_parse_mode`.
|
||||
Currently, only custom emoji entities are allowed.
|
||||
This list is empty if the text does not contain entities.
|
||||
|
||||
Attributes:
|
||||
text (:obj:`str`): Option text,
|
||||
:tg-const:`telegram.PollOption.MIN_LENGTH`-:tg-const:`telegram.PollOption.MAX_LENGTH`
|
||||
characters.
|
||||
text_parse_mode (:obj:`str`): Optional. |parse_mode|
|
||||
Currently, only custom emoji entities are allowed.
|
||||
text_entities (Sequence[:class:`telegram.MessageEntity`]): Special entities
|
||||
that appear in the option :paramref:`text`. It can be specified instead of
|
||||
:paramref:`text_parse_mode`.
|
||||
Currently, only custom emoji entities are allowed.
|
||||
This list is empty if the text does not contain entities.
|
||||
"""
|
||||
|
||||
__slots__ = ("text", "text_entities", "text_parse_mode")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
text: str,
|
||||
text_parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
text_entities: Optional[Sequence[MessageEntity]] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
self.text: str = text
|
||||
self.text_parse_mode: ODVInput[str] = text_parse_mode
|
||||
self.text_entities: Tuple[MessageEntity, ...] = parse_sequence_arg(text_entities)
|
||||
|
||||
self._id_attrs = (self.text,)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["InputPollOption"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data["text_entities"] = MessageEntity.de_list(data.get("text_entities"), bot)
|
||||
|
||||
return super().de_json(data=data, bot=bot)
|
||||
|
||||
|
||||
class PollOption(TelegramObject):
|
||||
"""
|
||||
This object contains information about one answer option in a poll.
|
||||
@@ -46,26 +114,101 @@ class PollOption(TelegramObject):
|
||||
:tg-const:`telegram.PollOption.MIN_LENGTH`-:tg-const:`telegram.PollOption.MAX_LENGTH`
|
||||
characters.
|
||||
voter_count (:obj:`int`): Number of users that voted for this option.
|
||||
text_entities (Sequence[:class:`telegram.MessageEntity`], optional): Special entities
|
||||
that appear in the option text. Currently, only custom emoji entities are allowed in
|
||||
poll option texts.
|
||||
|
||||
.. versionadded:: 21.2
|
||||
|
||||
Attributes:
|
||||
text (:obj:`str`): Option text,
|
||||
:tg-const:`telegram.PollOption.MIN_LENGTH`-:tg-const:`telegram.PollOption.MAX_LENGTH`
|
||||
characters.
|
||||
voter_count (:obj:`int`): Number of users that voted for this option.
|
||||
text_entities (Tuple[:class:`telegram.MessageEntity`]): Special entities
|
||||
that appear in the option text. Currently, only custom emoji entities are allowed in
|
||||
poll option texts.
|
||||
This list is empty if the question does not contain entities.
|
||||
|
||||
.. versionadded:: 21.2
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = ("text", "voter_count")
|
||||
__slots__ = ("text", "text_entities", "voter_count")
|
||||
|
||||
def __init__(self, text: str, voter_count: int, *, api_kwargs: Optional[JSONDict] = None):
|
||||
def __init__(
|
||||
self,
|
||||
text: str,
|
||||
voter_count: int,
|
||||
text_entities: Optional[Sequence[MessageEntity]] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
self.text: str = text
|
||||
self.voter_count: int = voter_count
|
||||
self.text_entities: Tuple[MessageEntity, ...] = parse_sequence_arg(text_entities)
|
||||
|
||||
self._id_attrs = (self.text, self.voter_count)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["PollOption"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data["text_entities"] = MessageEntity.de_list(data.get("text_entities"), bot)
|
||||
|
||||
return super().de_json(data=data, bot=bot)
|
||||
|
||||
def parse_entity(self, entity: MessageEntity) -> str:
|
||||
"""Returns the text in :attr:`text`
|
||||
from a given :class:`telegram.MessageEntity` of :attr:`text_entities`.
|
||||
|
||||
Note:
|
||||
This method is present because Telegram calculates the offset and length in
|
||||
UTF-16 codepoint pairs, which some versions of Python don't handle automatically.
|
||||
(That is, you can't just slice ``Message.text`` with the offset and length.)
|
||||
|
||||
.. versionadded:: 21.2
|
||||
|
||||
Args:
|
||||
entity (:class:`telegram.MessageEntity`): The entity to extract the text from. It must
|
||||
be an entity that belongs to :attr:`text_entities`.
|
||||
|
||||
Returns:
|
||||
:obj:`str`: The text of the given entity.
|
||||
"""
|
||||
return parse_message_entity(self.text, entity)
|
||||
|
||||
def parse_entities(self, types: Optional[List[str]] = None) -> Dict[MessageEntity, str]:
|
||||
"""
|
||||
Returns a :obj:`dict` that maps :class:`telegram.MessageEntity` to :obj:`str`.
|
||||
It contains entities from this polls question filtered by their ``type`` attribute as
|
||||
the key, and the text that each entity belongs to as the value of the :obj:`dict`.
|
||||
|
||||
Note:
|
||||
This method should always be used instead of the :attr:`text_entities`
|
||||
attribute, since it calculates the correct substring from the message text based on
|
||||
UTF-16 codepoints. See :attr:`parse_entity` for more info.
|
||||
|
||||
.. versionadded:: 21.2
|
||||
|
||||
Args:
|
||||
types (List[:obj:`str`], optional): List of ``MessageEntity`` types as strings. If the
|
||||
``type`` attribute of an entity is contained in this list, it will be returned.
|
||||
Defaults to :attr:`telegram.MessageEntity.ALL_TYPES`.
|
||||
|
||||
Returns:
|
||||
Dict[:class:`telegram.MessageEntity`, :obj:`str`]: A dictionary of entities mapped to
|
||||
the text that belongs to them, calculated based on UTF-16 codepoints.
|
||||
"""
|
||||
return parse_message_entities(self.text, self.text_entities, types)
|
||||
|
||||
MIN_LENGTH: Final[int] = constants.PollLimit.MIN_OPTION_LENGTH
|
||||
""":const:`telegram.constants.PollLimit.MIN_OPTION_LENGTH`
|
||||
|
||||
@@ -215,6 +358,11 @@ class Poll(TelegramObject):
|
||||
|
||||
.. versionchanged:: 20.3
|
||||
|datetime_localization|
|
||||
question_entities (Sequence[:class:`telegram.MessageEntity`], optional): Special entities
|
||||
that appear in the :attr:`question`. Currently, only custom emoji entities are allowed
|
||||
in poll questions.
|
||||
|
||||
.. versionadded:: 21.2
|
||||
|
||||
Attributes:
|
||||
id (:obj:`str`): Unique poll identifier.
|
||||
@@ -251,6 +399,12 @@ class Poll(TelegramObject):
|
||||
|
||||
.. versionchanged:: 20.3
|
||||
|datetime_localization|
|
||||
question_entities (Tuple[:class:`telegram.MessageEntity`]): Special entities
|
||||
that appear in the :attr:`question`. Currently, only custom emoji entities are allowed
|
||||
in poll questions.
|
||||
This list is empty if the question does not contain entities.
|
||||
|
||||
.. versionadded:: 21.2
|
||||
|
||||
"""
|
||||
|
||||
@@ -266,6 +420,7 @@ class Poll(TelegramObject):
|
||||
"open_period",
|
||||
"options",
|
||||
"question",
|
||||
"question_entities",
|
||||
"total_voter_count",
|
||||
"type",
|
||||
)
|
||||
@@ -285,6 +440,7 @@ class Poll(TelegramObject):
|
||||
explanation_entities: Optional[Sequence[MessageEntity]] = None,
|
||||
open_period: Optional[int] = None,
|
||||
close_date: Optional[datetime.datetime] = None,
|
||||
question_entities: Optional[Sequence[MessageEntity]] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
@@ -304,6 +460,7 @@ class Poll(TelegramObject):
|
||||
)
|
||||
self.open_period: Optional[int] = open_period
|
||||
self.close_date: Optional[datetime.datetime] = close_date
|
||||
self.question_entities: Tuple[MessageEntity, ...] = parse_sequence_arg(question_entities)
|
||||
|
||||
self._id_attrs = (self.id,)
|
||||
|
||||
@@ -323,11 +480,13 @@ class Poll(TelegramObject):
|
||||
data["options"] = [PollOption.de_json(option, bot) for option in data["options"]]
|
||||
data["explanation_entities"] = MessageEntity.de_list(data.get("explanation_entities"), bot)
|
||||
data["close_date"] = from_timestamp(data.get("close_date"), tzinfo=loc_tzinfo)
|
||||
data["question_entities"] = MessageEntity.de_list(data.get("question_entities"), bot)
|
||||
|
||||
return super().de_json(data=data, bot=bot)
|
||||
|
||||
def parse_explanation_entity(self, entity: MessageEntity) -> str:
|
||||
"""Returns the text from a given :class:`telegram.MessageEntity`.
|
||||
"""Returns the text in :attr:`explanation` from a given :class:`telegram.MessageEntity` of
|
||||
:attr:`explanation_entities`.
|
||||
|
||||
Note:
|
||||
This method is present because Telegram calculates the offset and length in
|
||||
@@ -336,7 +495,7 @@ class Poll(TelegramObject):
|
||||
|
||||
Args:
|
||||
entity (:class:`telegram.MessageEntity`): The entity to extract the text from. It must
|
||||
be an entity that belongs to this message.
|
||||
be an entity that belongs to :attr:`explanation_entities`.
|
||||
|
||||
Returns:
|
||||
:obj:`str`: The text of the given entity.
|
||||
@@ -348,10 +507,7 @@ class Poll(TelegramObject):
|
||||
if not self.explanation:
|
||||
raise RuntimeError("This Poll has no 'explanation'.")
|
||||
|
||||
entity_text = self.explanation.encode("utf-16-le")
|
||||
entity_text = entity_text[entity.offset * 2 : (entity.offset + entity.length) * 2]
|
||||
|
||||
return entity_text.decode("utf-16-le")
|
||||
return parse_message_entity(self.explanation, entity)
|
||||
|
||||
def parse_explanation_entities(
|
||||
self, types: Optional[List[str]] = None
|
||||
@@ -375,15 +531,61 @@ class Poll(TelegramObject):
|
||||
Dict[:class:`telegram.MessageEntity`, :obj:`str`]: A dictionary of entities mapped to
|
||||
the text that belongs to them, calculated based on UTF-16 codepoints.
|
||||
|
||||
"""
|
||||
if types is None:
|
||||
types = MessageEntity.ALL_TYPES
|
||||
Raises:
|
||||
RuntimeError: If the poll has no explanation.
|
||||
|
||||
return {
|
||||
entity: self.parse_explanation_entity(entity)
|
||||
for entity in self.explanation_entities
|
||||
if entity.type in types
|
||||
}
|
||||
"""
|
||||
if not self.explanation:
|
||||
raise RuntimeError("This Poll has no 'explanation'.")
|
||||
|
||||
return parse_message_entities(self.explanation, self.explanation_entities, types)
|
||||
|
||||
def parse_question_entity(self, entity: MessageEntity) -> str:
|
||||
"""Returns the text in :attr:`question` from a given :class:`telegram.MessageEntity` of
|
||||
:attr:`question_entities`.
|
||||
|
||||
.. versionadded:: 21.2
|
||||
|
||||
Note:
|
||||
This method is present because Telegram calculates the offset and length in
|
||||
UTF-16 codepoint pairs, which some versions of Python don't handle automatically.
|
||||
(That is, you can't just slice ``Message.text`` with the offset and length.)
|
||||
|
||||
Args:
|
||||
entity (:class:`telegram.MessageEntity`): The entity to extract the text from. It must
|
||||
be an entity that belongs to :attr:`question_entities`.
|
||||
|
||||
Returns:
|
||||
:obj:`str`: The text of the given entity.
|
||||
"""
|
||||
return parse_message_entity(self.question, entity)
|
||||
|
||||
def parse_question_entities(
|
||||
self, types: Optional[List[str]] = None
|
||||
) -> Dict[MessageEntity, str]:
|
||||
"""
|
||||
Returns a :obj:`dict` that maps :class:`telegram.MessageEntity` to :obj:`str`.
|
||||
It contains entities from this polls question filtered by their ``type`` attribute as
|
||||
the key, and the text that each entity belongs to as the value of the :obj:`dict`.
|
||||
|
||||
.. versionadded:: 21.2
|
||||
|
||||
Note:
|
||||
This method should always be used instead of the :attr:`question_entities`
|
||||
attribute, since it calculates the correct substring from the message text based on
|
||||
UTF-16 codepoints. See :attr:`parse_question_entity` for more info.
|
||||
|
||||
Args:
|
||||
types (List[:obj:`str`], optional): List of ``MessageEntity`` types as strings. If the
|
||||
``type`` attribute of an entity is contained in this list, it will be returned.
|
||||
Defaults to :attr:`telegram.MessageEntity.ALL_TYPES`.
|
||||
|
||||
Returns:
|
||||
Dict[:class:`telegram.MessageEntity`, :obj:`str`]: A dictionary of entities mapped to
|
||||
the text that belongs to them, calculated based on UTF-16 codepoints.
|
||||
|
||||
"""
|
||||
return parse_message_entities(self.question, self.question_entities, types)
|
||||
|
||||
REGULAR: Final[str] = constants.PollType.REGULAR
|
||||
""":const:`telegram.constants.PollType.REGULAR`"""
|
||||
|
||||
@@ -355,6 +355,7 @@ class ReplyParameters(TelegramObject):
|
||||
chat, or in the chat :paramref:`chat_id` if it is specified.
|
||||
chat_id (:obj:`int` | :obj:`str`, optional): If the message to be replied to is from a
|
||||
different chat, |chat_id_channel|
|
||||
Not supported for messages sent on behalf of a business account.
|
||||
allow_sending_without_reply (:obj:`bool`, optional): |allow_sending_without_reply| Can be
|
||||
used only for replies in the same chat and forum topic.
|
||||
quote (:obj:`str`, optional): Quoted part of the message to be replied to; 0-1024
|
||||
@@ -376,6 +377,7 @@ class ReplyParameters(TelegramObject):
|
||||
chat, or in the chat :paramref:`chat_id` if it is specified.
|
||||
chat_id (:obj:`int` | :obj:`str`): Optional. If the message to be replied to is from a
|
||||
different chat, |chat_id_channel|
|
||||
Not supported for messages sent on behalf of a business account.
|
||||
allow_sending_without_reply (:obj:`bool`): Optional. |allow_sending_without_reply| Can be
|
||||
used only for replies in the same chat and forum topic.
|
||||
quote (:obj:`str`): Optional. Quoted part of the message to be replied to; 0-1024
|
||||
|
||||
@@ -28,7 +28,8 @@ from telegram._utils.types import JSONDict
|
||||
|
||||
|
||||
class ReplyKeyboardMarkup(TelegramObject):
|
||||
"""This object represents a custom keyboard with reply options.
|
||||
"""This object represents a custom keyboard with reply options. Not supported in channels and
|
||||
for messages sent on behalf of a Telegram Business account.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their size of :attr:`keyboard` and all the buttons are equal.
|
||||
|
||||
@@ -29,6 +29,7 @@ class ReplyKeyboardRemove(TelegramObject):
|
||||
keyboard and display the default letter-keyboard. By default, custom keyboards are displayed
|
||||
until a new keyboard is sent by a bot. An exception is made for one-time keyboards that are
|
||||
hidden immediately after the user presses a button (see :class:`telegram.ReplyKeyboardMarkup`).
|
||||
Not supported in channels and for messages sent on behalf of a Telegram Business account.
|
||||
|
||||
Note:
|
||||
User will not be able to summon this keyboard; if you want to hide the keyboard from
|
||||
|
||||
+166
-20
@@ -17,11 +17,16 @@
|
||||
# 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 two objects used for request chats/users service messages."""
|
||||
from typing import Optional, Sequence, Tuple
|
||||
from typing import TYPE_CHECKING, Optional, Sequence, Tuple
|
||||
|
||||
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
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram._bot import Bot
|
||||
|
||||
|
||||
class UsersShared(TelegramObject):
|
||||
"""
|
||||
@@ -29,48 +34,72 @@ class UsersShared(TelegramObject):
|
||||
using a :class:`telegram.KeyboardButtonRequestUsers` button.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`request_id` and :attr:`user_ids` are equal.
|
||||
considered equal, if their :attr:`request_id` and :attr:`users` are equal.
|
||||
|
||||
.. versionadded:: 20.8
|
||||
Bot API 7.0 replaces ``UserShared`` with this class. The only difference is that now
|
||||
the :attr:`user_ids` is a sequence instead of a single integer.
|
||||
the ``user_ids`` is a sequence instead of a single integer.
|
||||
|
||||
.. versionchanged:: 21.1
|
||||
The argument :attr:`users` is now considered for the equality comparison instead of
|
||||
``user_ids``.
|
||||
|
||||
.. versionremoved:: 21.2
|
||||
Removed the deprecated argument and attribute ``user_ids``.
|
||||
|
||||
Args:
|
||||
request_id (:obj:`int`): Identifier of the request.
|
||||
user_ids (Sequence[:obj:`int`]): Identifiers of the shared users. These numbers may have
|
||||
more than 32 significant bits and some programming languages may have difficulty/silent
|
||||
defects in interpreting them. But they have at most 52 significant bits, so 64-bit
|
||||
integers or double-precision float types are safe for storing these identifiers. The
|
||||
bot may not have access to the users and could be unable to use these identifiers,
|
||||
unless the users are already known to the bot by some other means.
|
||||
users (Sequence[:class:`telegram.SharedUser`]): Information about users shared with the
|
||||
bot.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
|
||||
.. versionchanged:: 21.2
|
||||
This argument is now required.
|
||||
|
||||
Attributes:
|
||||
request_id (:obj:`int`): Identifier of the request.
|
||||
user_ids (Tuple[:obj:`int`]): Identifiers of the shared users. These numbers may have
|
||||
more than 32 significant bits and some programming languages may have difficulty/silent
|
||||
defects in interpreting them. But they have at most 52 significant bits, so 64-bit
|
||||
integers or double-precision float types are safe for storing these identifiers. The
|
||||
bot may not have access to the users and could be unable to use these identifiers,
|
||||
unless the users are already known to the bot by some other means.
|
||||
users (Tuple[:class:`telegram.SharedUser`]): Information about users shared with the
|
||||
bot.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
"""
|
||||
|
||||
__slots__ = ("request_id", "user_ids")
|
||||
__slots__ = ("request_id", "users")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
request_id: int,
|
||||
user_ids: Sequence[int],
|
||||
users: Sequence["SharedUser"],
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
self.request_id: int = request_id
|
||||
self.user_ids: Tuple[int, ...] = tuple(user_ids)
|
||||
self.users: Tuple[SharedUser, ...] = parse_sequence_arg(users)
|
||||
|
||||
self._id_attrs = (self.request_id, self.user_ids)
|
||||
self._id_attrs = (self.request_id, self.users)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["UsersShared"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data["users"] = SharedUser.de_list(data.get("users"), bot)
|
||||
|
||||
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 user_ids := data.get("user_ids"):
|
||||
api_kwargs = {"user_ids": user_ids}
|
||||
|
||||
return super()._de_json(data=data, bot=bot, api_kwargs=api_kwargs)
|
||||
|
||||
|
||||
class ChatShared(TelegramObject):
|
||||
"""
|
||||
@@ -88,6 +117,17 @@ class ChatShared(TelegramObject):
|
||||
bits and some programming languages may have difficulty/silent defects in interpreting
|
||||
it. But it is smaller than 52 bits, so a signed 64-bit integer or double-precision
|
||||
float type are safe for storing this identifier.
|
||||
title (:obj:`str`, optional): Title of the chat, if the title was requested by the bot.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
username (:obj:`str`, optional): Username of the chat, if the username was requested by
|
||||
the bot and available.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
photo (Sequence[:class:`telegram.PhotoSize`], optional): Available sizes of the chat photo,
|
||||
if the photo was requested by the bot
|
||||
|
||||
.. versionadded:: 21.1
|
||||
|
||||
Attributes:
|
||||
request_id (:obj:`int`): Identifier of the request.
|
||||
@@ -95,21 +135,127 @@ class ChatShared(TelegramObject):
|
||||
bits and some programming languages may have difficulty/silent defects in interpreting
|
||||
it. But it is smaller than 52 bits, so a signed 64-bit integer or double-precision
|
||||
float type are safe for storing this identifier.
|
||||
title (:obj:`str`): Optional. Title of the chat, if the title was requested by the bot.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
username (:obj:`str`): Optional. Username of the chat, if the username was requested by
|
||||
the bot and available.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
photo (Tuple[:class:`telegram.PhotoSize`]): Optional. Available sizes of the chat photo,
|
||||
if the photo was requested by the bot
|
||||
|
||||
.. versionadded:: 21.1
|
||||
"""
|
||||
|
||||
__slots__ = ("chat_id", "request_id")
|
||||
__slots__ = ("chat_id", "photo", "request_id", "title", "username")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
request_id: int,
|
||||
chat_id: int,
|
||||
title: Optional[str] = None,
|
||||
username: Optional[str] = None,
|
||||
photo: Optional[Sequence[PhotoSize]] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
self.request_id: int = request_id
|
||||
self.chat_id: int = chat_id
|
||||
self.title: Optional[str] = title
|
||||
self.username: Optional[str] = username
|
||||
self.photo: Optional[Tuple[PhotoSize, ...]] = parse_sequence_arg(photo)
|
||||
|
||||
self._id_attrs = (self.request_id, self.chat_id)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["ChatShared"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data["photo"] = PhotoSize.de_list(data.get("photo"), bot)
|
||||
return super().de_json(data=data, bot=bot)
|
||||
|
||||
|
||||
class SharedUser(TelegramObject):
|
||||
"""
|
||||
This object contains information about a user that was shared with the bot using a
|
||||
:class:`telegram.KeyboardButtonRequestUsers` button.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`user_id` is equal.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
|
||||
Args:
|
||||
user_id (:obj:`int`): Identifier of the shared user. This number may have 32 significant
|
||||
bits and some programming languages may have difficulty/silent defects in interpreting
|
||||
it. But it has atmost 52 significant bits, so 64-bit integers or double-precision
|
||||
float types are safe for storing these identifiers. The bot may not have access to the
|
||||
user and could be unable to use this identifier, unless the user is already known to
|
||||
the bot by some other means.
|
||||
first_name (:obj:`str`, optional): First name of the user, if the name was requested by the
|
||||
bot.
|
||||
last_name (:obj:`str`, optional): Last name of the user, if the name was requested by the
|
||||
bot.
|
||||
username (:obj:`str`, optional): Username of the user, if the username was requested by the
|
||||
bot.
|
||||
photo (Sequence[:class:`telegram.PhotoSize`], optional): Available sizes of the chat photo,
|
||||
if the photo was requested by the bot.
|
||||
|
||||
Attributes:
|
||||
user_id (:obj:`int`): Identifier of the shared user. This number may have 32 significant
|
||||
bits and some programming languages may have difficulty/silent defects in interpreting
|
||||
it. But it has atmost 52 significant bits, so 64-bit integers or double-precision
|
||||
float types are safe for storing these identifiers. The bot may not have access to the
|
||||
user and could be unable to use this identifier, unless the user is already known to
|
||||
the bot by some other means.
|
||||
first_name (:obj:`str`): Optional. First name of the user, if the name was requested by the
|
||||
bot.
|
||||
last_name (:obj:`str`): Optional. Last name of the user, if the name was requested by the
|
||||
bot.
|
||||
username (:obj:`str`): Optional. Username of the user, if the username was requested by the
|
||||
bot.
|
||||
photo (Tuple[:class:`telegram.PhotoSize`]): Available sizes of the chat photo, if
|
||||
the photo was requested by the bot. This list is empty if the photo was not requsted.
|
||||
"""
|
||||
|
||||
__slots__ = ("first_name", "last_name", "photo", "user_id", "username")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
user_id: int,
|
||||
first_name: Optional[str] = None,
|
||||
last_name: Optional[str] = None,
|
||||
username: Optional[str] = None,
|
||||
photo: Optional[Sequence[PhotoSize]] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
self.user_id: int = user_id
|
||||
self.first_name: Optional[str] = first_name
|
||||
self.last_name: Optional[str] = last_name
|
||||
self.username: Optional[str] = username
|
||||
self.photo: Optional[Tuple[PhotoSize, ...]] = parse_sequence_arg(photo)
|
||||
|
||||
self._id_attrs = (self.user_id,)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["SharedUser"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data["photo"] = PhotoSize.de_list(data.get("photo"), bot)
|
||||
return super().de_json(data=data, bot=bot)
|
||||
|
||||
+182
-3
@@ -18,9 +18,10 @@
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram Update."""
|
||||
|
||||
from typing import TYPE_CHECKING, Final, List, Optional
|
||||
from typing import TYPE_CHECKING, Final, List, Optional, Union
|
||||
|
||||
from telegram import constants
|
||||
from telegram._business import BusinessConnection, BusinessMessagesDeleted
|
||||
from telegram._callbackquery import CallbackQuery
|
||||
from telegram._chatboost import ChatBoostRemoved, ChatBoostUpdated
|
||||
from telegram._chatjoinrequest import ChatJoinRequest
|
||||
@@ -134,6 +135,28 @@ class Update(TelegramObject):
|
||||
|
||||
.. versionadded:: 20.8
|
||||
|
||||
business_connection (:class:`telegram.BusinessConnection`, optional): The bot was connected
|
||||
to or disconnected from a business account, or a user edited an existing connection
|
||||
with the bot.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
|
||||
business_message (:class:`telegram.Message`, optional): New message from a connected
|
||||
business account.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
|
||||
edited_business_message (:class:`telegram.Message`, optional): New version of a message
|
||||
from a connected business account.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
|
||||
deleted_business_messages (:class:`telegram.BusinessMessagesDeleted`, optional): Messages
|
||||
were deleted from a connected business account.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
|
||||
|
||||
Attributes:
|
||||
update_id (:obj:`int`): The update's unique identifier. Update identifiers start from a
|
||||
certain positive number and increase sequentially. This ID becomes especially handy if
|
||||
@@ -219,18 +242,44 @@ class Update(TelegramObject):
|
||||
with delay up to a few minutes.
|
||||
|
||||
.. versionadded:: 20.8
|
||||
|
||||
business_connection (:class:`telegram.BusinessConnection`): Optional. The bot was connected
|
||||
to or disconnected from a business account, or a user edited an existing connection
|
||||
with the bot.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
|
||||
business_message (:class:`telegram.Message`): Optional. New message from a connected
|
||||
business account.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
|
||||
edited_business_message (:class:`telegram.Message`): Optional. New version of a message
|
||||
from a connected business account.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
|
||||
deleted_business_messages (:class:`telegram.BusinessMessagesDeleted`): Optional. Messages
|
||||
were deleted from a connected business account.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
"""
|
||||
|
||||
__slots__ = (
|
||||
"_effective_chat",
|
||||
"_effective_message",
|
||||
"_effective_sender",
|
||||
"_effective_user",
|
||||
"business_connection",
|
||||
"business_message",
|
||||
"callback_query",
|
||||
"channel_post",
|
||||
"chat_boost",
|
||||
"chat_join_request",
|
||||
"chat_member",
|
||||
"chosen_inline_result",
|
||||
"deleted_business_messages",
|
||||
"edited_business_message",
|
||||
"edited_channel_post",
|
||||
"edited_message",
|
||||
"inline_query",
|
||||
@@ -318,6 +367,22 @@ class Update(TelegramObject):
|
||||
""":const:`telegram.constants.UpdateType.MESSAGE_REACTION_COUNT`
|
||||
|
||||
.. versionadded:: 20.8"""
|
||||
BUSINESS_CONNECTION: Final[str] = constants.UpdateType.BUSINESS_CONNECTION
|
||||
""":const:`telegram.constants.UpdateType.BUSINESS_CONNECTION`
|
||||
|
||||
.. versionadded:: 21.1"""
|
||||
BUSINESS_MESSAGE: Final[str] = constants.UpdateType.BUSINESS_MESSAGE
|
||||
""":const:`telegram.constants.UpdateType.BUSINESS_MESSAGE`
|
||||
|
||||
.. versionadded:: 21.1"""
|
||||
EDITED_BUSINESS_MESSAGE: Final[str] = constants.UpdateType.EDITED_BUSINESS_MESSAGE
|
||||
""":const:`telegram.constants.UpdateType.EDITED_BUSINESS_MESSAGE`
|
||||
|
||||
.. versionadded:: 21.1"""
|
||||
DELETED_BUSINESS_MESSAGES: Final[str] = constants.UpdateType.DELETED_BUSINESS_MESSAGES
|
||||
""":const:`telegram.constants.UpdateType.DELETED_BUSINESS_MESSAGES`
|
||||
|
||||
.. versionadded:: 21.1"""
|
||||
ALL_TYPES: Final[List[str]] = list(constants.UpdateType)
|
||||
"""List[:obj:`str`]: A list of all available update types.
|
||||
|
||||
@@ -344,6 +409,10 @@ class Update(TelegramObject):
|
||||
removed_chat_boost: Optional[ChatBoostRemoved] = None,
|
||||
message_reaction: Optional[MessageReactionUpdated] = None,
|
||||
message_reaction_count: Optional[MessageReactionCountUpdated] = None,
|
||||
business_connection: Optional[BusinessConnection] = None,
|
||||
business_message: Optional[Message] = None,
|
||||
edited_business_message: Optional[Message] = None,
|
||||
deleted_business_messages: Optional[BusinessMessagesDeleted] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
@@ -369,8 +438,15 @@ class Update(TelegramObject):
|
||||
self.removed_chat_boost: Optional[ChatBoostRemoved] = removed_chat_boost
|
||||
self.message_reaction: Optional[MessageReactionUpdated] = message_reaction
|
||||
self.message_reaction_count: Optional[MessageReactionCountUpdated] = message_reaction_count
|
||||
self.business_connection: Optional[BusinessConnection] = business_connection
|
||||
self.business_message: Optional[Message] = business_message
|
||||
self.edited_business_message: Optional[Message] = edited_business_message
|
||||
self.deleted_business_messages: Optional[BusinessMessagesDeleted] = (
|
||||
deleted_business_messages
|
||||
)
|
||||
|
||||
self._effective_user: Optional[User] = None
|
||||
self._effective_sender: Optional[Union["User", "Chat"]] = None
|
||||
self._effective_chat: Optional[Chat] = None
|
||||
self._effective_message: Optional[Message] = None
|
||||
|
||||
@@ -391,9 +467,14 @@ class Update(TelegramObject):
|
||||
* :attr:`chat_boost`
|
||||
* :attr:`removed_chat_boost`
|
||||
* :attr:`message_reaction_count`
|
||||
* :attr:`deleted_business_messages`
|
||||
|
||||
is present.
|
||||
|
||||
.. versionchanged:: 21.1
|
||||
This property now also considers :attr:`business_connection`, :attr:`business_message`
|
||||
and :attr:`edited_business_message`.
|
||||
|
||||
Example:
|
||||
* If :attr:`message` is present, this will give
|
||||
:attr:`telegram.Message.from_user`.
|
||||
@@ -441,9 +522,76 @@ class Update(TelegramObject):
|
||||
elif self.message_reaction:
|
||||
user = self.message_reaction.user
|
||||
|
||||
elif self.business_message:
|
||||
user = self.business_message.from_user
|
||||
|
||||
elif self.edited_business_message:
|
||||
user = self.edited_business_message.from_user
|
||||
|
||||
elif self.business_connection:
|
||||
user = self.business_connection.user
|
||||
|
||||
self._effective_user = user
|
||||
return user
|
||||
|
||||
@property
|
||||
def effective_sender(self) -> Optional[Union["User", "Chat"]]:
|
||||
"""
|
||||
:class:`telegram.User` or :class:`telegram.Chat`: The user or chat that sent this update,
|
||||
no matter what kind of update this is.
|
||||
|
||||
Note:
|
||||
* Depending on the type of update and the user's 'Remain anonymous' setting, this
|
||||
could either be :class:`telegram.User`, :class:`telegram.Chat` or :obj:`None`.
|
||||
|
||||
If no user whatsoever is associated with this update, this gives :obj:`None`. This
|
||||
is the case if any of
|
||||
|
||||
* :attr:`poll`
|
||||
* :attr:`chat_boost`
|
||||
* :attr:`removed_chat_boost`
|
||||
* :attr:`message_reaction_count`
|
||||
* :attr:`deleted_business_messages`
|
||||
|
||||
is present.
|
||||
|
||||
Example:
|
||||
* If :attr:`message` is present, this will give either
|
||||
:attr:`telegram.Message.from_user` or :attr:`telegram.Message.sender_chat`.
|
||||
* If :attr:`poll_answer` is present, this will give either
|
||||
:attr:`telegram.PollAnswer.user` or :attr:`telegram.PollAnswer.voter_chat`.
|
||||
* If :attr:`channel_post` is present, this will give
|
||||
:attr:`telegram.Message.sender_chat`.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
"""
|
||||
if self._effective_sender:
|
||||
return self._effective_sender
|
||||
|
||||
sender: Optional[Union["User", "Chat"]] = None
|
||||
|
||||
if message := (
|
||||
self.message
|
||||
or self.edited_message
|
||||
or self.channel_post
|
||||
or self.edited_channel_post
|
||||
or self.business_message
|
||||
or self.edited_business_message
|
||||
):
|
||||
sender = message.sender_chat
|
||||
|
||||
elif self.poll_answer:
|
||||
sender = self.poll_answer.voter_chat
|
||||
|
||||
elif self.message_reaction:
|
||||
sender = self.message_reaction.actor_chat
|
||||
|
||||
if sender is None:
|
||||
sender = self.effective_user
|
||||
|
||||
self._effective_sender = sender
|
||||
return sender
|
||||
|
||||
@property
|
||||
def effective_chat(self) -> Optional["Chat"]:
|
||||
"""
|
||||
@@ -452,8 +600,12 @@ class Update(TelegramObject):
|
||||
If no chat is associated with this update, this gives :obj:`None`.
|
||||
This is the case, if :attr:`inline_query`,
|
||||
:attr:`chosen_inline_result`, :attr:`callback_query` from inline messages,
|
||||
:attr:`shipping_query`, :attr:`pre_checkout_query`, :attr:`poll` or
|
||||
:attr:`poll_answer` is present.
|
||||
:attr:`shipping_query`, :attr:`pre_checkout_query`, :attr:`poll`,
|
||||
:attr:`poll_answer`, or :attr:`business_connection` is present.
|
||||
|
||||
.. versionchanged:: 21.1
|
||||
This property now also considers :attr:`business_message`,
|
||||
:attr:`edited_business_message`, and :attr:`deleted_business_messages`.
|
||||
|
||||
Example:
|
||||
If :attr:`message` is present, this will give :attr:`telegram.Message.chat`.
|
||||
@@ -500,6 +652,15 @@ class Update(TelegramObject):
|
||||
elif self.message_reaction_count:
|
||||
chat = self.message_reaction_count.chat
|
||||
|
||||
elif self.business_message:
|
||||
chat = self.business_message.chat
|
||||
|
||||
elif self.edited_business_message:
|
||||
chat = self.edited_business_message.chat
|
||||
|
||||
elif self.deleted_business_messages:
|
||||
chat = self.deleted_business_messages.chat
|
||||
|
||||
self._effective_chat = chat
|
||||
return chat
|
||||
|
||||
@@ -512,6 +673,10 @@ class Update(TelegramObject):
|
||||
:attr:`callback_query` (i.e. :attr:`telegram.CallbackQuery.message`) or :obj:`None`, if
|
||||
none of those are present.
|
||||
|
||||
.. versionchanged:: 21.1
|
||||
This property now also considers :attr:`business_message`, and
|
||||
:attr:`edited_business_message`.
|
||||
|
||||
Tip:
|
||||
This property will only ever return objects of type :class:`telegram.Message` or
|
||||
:obj:`None`, never :class:`telegram.MaybeInaccessibleMessage` or
|
||||
@@ -554,6 +719,12 @@ class Update(TelegramObject):
|
||||
elif self.edited_channel_post:
|
||||
message = self.edited_channel_post
|
||||
|
||||
elif self.business_message:
|
||||
message = self.business_message
|
||||
|
||||
elif self.edited_business_message:
|
||||
message = self.edited_business_message
|
||||
|
||||
self._effective_message = message
|
||||
return message
|
||||
|
||||
@@ -589,5 +760,13 @@ class Update(TelegramObject):
|
||||
data["message_reaction_count"] = MessageReactionCountUpdated.de_json(
|
||||
data.get("message_reaction_count"), bot
|
||||
)
|
||||
data["business_connection"] = BusinessConnection.de_json(
|
||||
data.get("business_connection"), bot
|
||||
)
|
||||
data["business_message"] = Message.de_json(data.get("business_message"), bot)
|
||||
data["edited_business_message"] = Message.de_json(data.get("edited_business_message"), bot)
|
||||
data["deleted_business_messages"] = BusinessMessagesDeleted.de_json(
|
||||
data.get("deleted_business_messages"), bot
|
||||
)
|
||||
|
||||
return super().de_json(data=data, bot=bot)
|
||||
|
||||
+134
-5
@@ -40,6 +40,7 @@ if TYPE_CHECKING:
|
||||
InputMediaDocument,
|
||||
InputMediaPhoto,
|
||||
InputMediaVideo,
|
||||
InputPollOption,
|
||||
LabeledPrice,
|
||||
LinkPreviewOptions,
|
||||
Location,
|
||||
@@ -78,11 +79,11 @@ class User(TelegramObject):
|
||||
username (:obj:`str`, optional): User's or bot's username.
|
||||
language_code (:obj:`str`, optional): IETF language tag of the user's language.
|
||||
can_join_groups (:obj:`str`, optional): :obj:`True`, if the bot can be invited to groups.
|
||||
Returned only in :attr:`telegram.Bot.get_me` requests.
|
||||
Returned only in :meth:`telegram.Bot.get_me`.
|
||||
can_read_all_group_messages (:obj:`str`, optional): :obj:`True`, if privacy mode is
|
||||
disabled for the bot. Returned only in :attr:`telegram.Bot.get_me` requests.
|
||||
disabled for the bot. Returned only in :meth:`telegram.Bot.get_me`.
|
||||
supports_inline_queries (:obj:`str`, optional): :obj:`True`, if the bot supports inline
|
||||
queries. Returned only in :attr:`telegram.Bot.get_me` requests.
|
||||
queries. Returned only in :meth:`telegram.Bot.get_me`.
|
||||
|
||||
is_premium (:obj:`bool`, optional): :obj:`True`, if this user is a Telegram Premium user.
|
||||
|
||||
@@ -91,6 +92,12 @@ class User(TelegramObject):
|
||||
the bot to the attachment menu.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
can_connect_to_business (:obj:`bool`, optional): :obj:`True`, if the bot can be connected
|
||||
to a Telegram Business account to receive its messages. Returned only in
|
||||
:meth:`telegram.Bot.get_me`.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
|
||||
Attributes:
|
||||
id (:obj:`int`): Unique identifier for this user or bot.
|
||||
is_bot (:obj:`bool`): :obj:`True`, if this user is a bot.
|
||||
@@ -112,6 +119,11 @@ class User(TelegramObject):
|
||||
the bot to the attachment menu.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
can_connect_to_business (:obj:`bool`): Optional. :obj:`True`, if the bot can be connected
|
||||
to a Telegram Business account to receive its messages. Returned only in
|
||||
:meth:`telegram.Bot.get_me`.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
.. |user_chat_id_note| replace:: This shortcuts build on the assumption that :attr:`User.id`
|
||||
coincides with the :attr:`Chat.id` of the private chat with the user. This has been the
|
||||
case so far, but Telegram does not guarantee that this stays this way.
|
||||
@@ -119,6 +131,7 @@ class User(TelegramObject):
|
||||
|
||||
__slots__ = (
|
||||
"added_to_attachment_menu",
|
||||
"can_connect_to_business",
|
||||
"can_join_groups",
|
||||
"can_read_all_group_messages",
|
||||
"first_name",
|
||||
@@ -144,6 +157,7 @@ class User(TelegramObject):
|
||||
supports_inline_queries: Optional[bool] = None,
|
||||
is_premium: Optional[bool] = None,
|
||||
added_to_attachment_menu: Optional[bool] = None,
|
||||
can_connect_to_business: Optional[bool] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
@@ -161,6 +175,7 @@ class User(TelegramObject):
|
||||
self.supports_inline_queries: Optional[bool] = supports_inline_queries
|
||||
self.is_premium: Optional[bool] = is_premium
|
||||
self.added_to_attachment_menu: Optional[bool] = added_to_attachment_menu
|
||||
self.can_connect_to_business: Optional[bool] = can_connect_to_business
|
||||
|
||||
self._id_attrs = (self.id,)
|
||||
|
||||
@@ -393,6 +408,8 @@ class User(TelegramObject):
|
||||
message_thread_id: Optional[int] = None,
|
||||
link_preview_options: ODVInput["LinkPreviewOptions"] = DEFAULT_NONE,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
disable_web_page_preview: Optional[bool] = None,
|
||||
@@ -435,6 +452,8 @@ class User(TelegramObject):
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def delete_message(
|
||||
@@ -513,6 +532,9 @@ class User(TelegramObject):
|
||||
message_thread_id: Optional[int] = None,
|
||||
has_spoiler: Optional[bool] = None,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
show_caption_above_media: Optional[bool] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -556,6 +578,9 @@ class User(TelegramObject):
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
has_spoiler=has_spoiler,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
show_caption_above_media=show_caption_above_media,
|
||||
)
|
||||
|
||||
async def send_media_group(
|
||||
@@ -567,6 +592,8 @@ class User(TelegramObject):
|
||||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
message_thread_id: Optional[int] = None,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -610,6 +637,8 @@ class User(TelegramObject):
|
||||
caption=caption,
|
||||
parse_mode=parse_mode,
|
||||
caption_entities=caption_entities,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def send_audio(
|
||||
@@ -627,6 +656,8 @@ class User(TelegramObject):
|
||||
message_thread_id: Optional[int] = None,
|
||||
thumbnail: Optional[FileInput] = None,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -673,12 +704,15 @@ class User(TelegramObject):
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
thumbnail=thumbnail,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def send_chat_action(
|
||||
self,
|
||||
action: str,
|
||||
message_thread_id: Optional[int] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
@@ -708,6 +742,7 @@ class User(TelegramObject):
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
business_connection_id=business_connection_id,
|
||||
)
|
||||
|
||||
send_action = send_chat_action
|
||||
@@ -724,6 +759,8 @@ class User(TelegramObject):
|
||||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
message_thread_id: Optional[int] = None,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -766,6 +803,8 @@ class User(TelegramObject):
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def send_dice(
|
||||
@@ -776,6 +815,8 @@ class User(TelegramObject):
|
||||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
message_thread_id: Optional[int] = None,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -813,6 +854,8 @@ class User(TelegramObject):
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def send_document(
|
||||
@@ -828,6 +871,8 @@ class User(TelegramObject):
|
||||
message_thread_id: Optional[int] = None,
|
||||
thumbnail: Optional[FileInput] = None,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -872,6 +917,8 @@ class User(TelegramObject):
|
||||
caption_entities=caption_entities,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def send_game(
|
||||
@@ -882,6 +929,8 @@ class User(TelegramObject):
|
||||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
message_thread_id: Optional[int] = None,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -919,6 +968,8 @@ class User(TelegramObject):
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def send_invoice(
|
||||
@@ -926,7 +977,7 @@ class User(TelegramObject):
|
||||
title: str,
|
||||
description: str,
|
||||
payload: str,
|
||||
provider_token: str,
|
||||
provider_token: Optional[str],
|
||||
currency: str,
|
||||
prices: Sequence["LabeledPrice"],
|
||||
start_parameter: Optional[str] = None,
|
||||
@@ -949,6 +1000,7 @@ class User(TelegramObject):
|
||||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
message_thread_id: Optional[int] = None,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -1016,6 +1068,7 @@ class User(TelegramObject):
|
||||
suggested_tip_amounts=suggested_tip_amounts,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def send_location(
|
||||
@@ -1031,6 +1084,8 @@ class User(TelegramObject):
|
||||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
message_thread_id: Optional[int] = None,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -1075,6 +1130,8 @@ class User(TelegramObject):
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def send_animation(
|
||||
@@ -1093,6 +1150,9 @@ class User(TelegramObject):
|
||||
has_spoiler: Optional[bool] = None,
|
||||
thumbnail: Optional[FileInput] = None,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
show_caption_above_media: Optional[bool] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -1140,6 +1200,9 @@ class User(TelegramObject):
|
||||
message_thread_id=message_thread_id,
|
||||
has_spoiler=has_spoiler,
|
||||
thumbnail=thumbnail,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
show_caption_above_media=show_caption_above_media,
|
||||
)
|
||||
|
||||
async def send_sticker(
|
||||
@@ -1151,6 +1214,8 @@ class User(TelegramObject):
|
||||
message_thread_id: Optional[int] = None,
|
||||
emoji: Optional[str] = None,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -1189,6 +1254,8 @@ class User(TelegramObject):
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
emoji=emoji,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def send_video(
|
||||
@@ -1208,6 +1275,9 @@ class User(TelegramObject):
|
||||
has_spoiler: Optional[bool] = None,
|
||||
thumbnail: Optional[FileInput] = None,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
show_caption_above_media: Optional[bool] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -1256,6 +1326,9 @@ class User(TelegramObject):
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
has_spoiler=has_spoiler,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
show_caption_above_media=show_caption_above_media,
|
||||
)
|
||||
|
||||
async def send_venue(
|
||||
@@ -1273,6 +1346,8 @@ class User(TelegramObject):
|
||||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
message_thread_id: Optional[int] = None,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -1319,6 +1394,8 @@ class User(TelegramObject):
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def send_video_note(
|
||||
@@ -1332,6 +1409,8 @@ class User(TelegramObject):
|
||||
message_thread_id: Optional[int] = None,
|
||||
thumbnail: Optional[FileInput] = None,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -1374,6 +1453,8 @@ class User(TelegramObject):
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
thumbnail=thumbnail,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def send_voice(
|
||||
@@ -1388,6 +1469,8 @@ class User(TelegramObject):
|
||||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
message_thread_id: Optional[int] = None,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -1431,12 +1514,14 @@ class User(TelegramObject):
|
||||
filename=filename,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def send_poll(
|
||||
self,
|
||||
question: str,
|
||||
options: Sequence[str],
|
||||
options: Sequence[Union[str, "InputPollOption"]],
|
||||
is_anonymous: Optional[bool] = None,
|
||||
type: Optional[str] = None,
|
||||
allows_multiple_answers: Optional[bool] = None,
|
||||
@@ -1452,6 +1537,10 @@ class User(TelegramObject):
|
||||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
message_thread_id: Optional[int] = None,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
question_parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
question_entities: Optional[Sequence["MessageEntity"]] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -1500,6 +1589,10 @@ class User(TelegramObject):
|
||||
explanation_entities=explanation_entities,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
business_connection_id=business_connection_id,
|
||||
question_parse_mode=question_parse_mode,
|
||||
question_entities=question_entities,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def send_copy(
|
||||
@@ -1514,6 +1607,7 @@ class User(TelegramObject):
|
||||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
message_thread_id: Optional[int] = None,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
show_caption_above_media: Optional[bool] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -1555,6 +1649,7 @@ class User(TelegramObject):
|
||||
api_kwargs=api_kwargs,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
show_caption_above_media=show_caption_above_media,
|
||||
)
|
||||
|
||||
async def copy_message(
|
||||
@@ -1569,6 +1664,7 @@ class User(TelegramObject):
|
||||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
message_thread_id: Optional[int] = None,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
show_caption_above_media: Optional[bool] = None,
|
||||
*,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
@@ -1610,6 +1706,7 @@ class User(TelegramObject):
|
||||
api_kwargs=api_kwargs,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
show_caption_above_media=show_caption_above_media,
|
||||
)
|
||||
|
||||
async def send_copies(
|
||||
@@ -2048,3 +2145,35 @@ class User(TelegramObject):
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
async def refund_star_payment(
|
||||
self,
|
||||
telegram_payment_charge_id: str,
|
||||
*,
|
||||
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.refund_star_payment(user_id=update.effective_user.id, *args, **kwargs)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.refund_star_payment`.
|
||||
|
||||
.. versionadded:: 21.3
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
"""
|
||||
return await self.get_bot().refund_star_payment(
|
||||
user_id=self.id,
|
||||
telegram_payment_charge_id=telegram_payment_charge_id,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
@@ -194,7 +194,7 @@ def extract_tzinfo_from_defaults(bot: "Bot") -> Union[dtm.tzinfo, None]:
|
||||
If the bot has no default values, :obj:`None` is returned.
|
||||
"""
|
||||
# We don't use `ininstance(bot, ExtBot)` here so that this works
|
||||
# in `python-telegram-bot-raw` as well
|
||||
# without the job-queue extra dependencies as well
|
||||
if hasattr(bot, "defaults") and bot.defaults:
|
||||
return bot.defaults.tzinfo
|
||||
return None
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2024
|
||||
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains auxiliary functionality for parsing MessageEntity objects.
|
||||
|
||||
Warning:
|
||||
Contents of this module are intended to be used internally by the library and *not* by the
|
||||
user. Changes to this module are not considered breaking changes and may not be documented in
|
||||
the changelog.
|
||||
"""
|
||||
from typing import Dict, Optional, Sequence
|
||||
|
||||
from telegram._messageentity import MessageEntity
|
||||
|
||||
|
||||
def parse_message_entity(text: str, entity: MessageEntity) -> str:
|
||||
"""Returns the text from a given :class:`telegram.MessageEntity`.
|
||||
|
||||
Args:
|
||||
text (:obj:`str`): The text to extract the entity from.
|
||||
entity (:class:`telegram.MessageEntity`): The entity to extract the text from.
|
||||
|
||||
Returns:
|
||||
:obj:`str`: The text of the given entity.
|
||||
"""
|
||||
entity_text = text.encode("utf-16-le")
|
||||
entity_text = entity_text[entity.offset * 2 : (entity.offset + entity.length) * 2]
|
||||
|
||||
return entity_text.decode("utf-16-le")
|
||||
|
||||
|
||||
def parse_message_entities(
|
||||
text: str, entities: Sequence[MessageEntity], types: Optional[Sequence[str]] = None
|
||||
) -> Dict[MessageEntity, str]:
|
||||
"""
|
||||
Returns a :obj:`dict` that maps :class:`telegram.MessageEntity` to :obj:`str`.
|
||||
It contains entities filtered by their ``type`` attribute as
|
||||
the key, and the text that each entity belongs to as the value of the :obj:`dict`.
|
||||
|
||||
Args:
|
||||
text (:obj:`str`): The text to extract the entity from.
|
||||
entities (List[:class:`telegram.MessageEntity`]): The entities to extract the text from.
|
||||
types (List[:obj:`str`], optional): List of ``MessageEntity`` types as strings. If the
|
||||
``type`` attribute of an entity is contained in this list, it will be returned.
|
||||
Defaults to :attr:`telegram.MessageEntity.ALL_TYPES`.
|
||||
|
||||
Returns:
|
||||
Dict[:class:`telegram.MessageEntity`, :obj:`str`]: A dictionary of entities mapped to
|
||||
the text that belongs to them, calculated based on UTF-16 codepoints.
|
||||
"""
|
||||
if types is None:
|
||||
types = MessageEntity.ALL_TYPES
|
||||
|
||||
return {
|
||||
entity: parse_message_entity(text, entity) for entity in entities if entity.type in types
|
||||
}
|
||||
@@ -60,7 +60,7 @@ class StringEnum(str, _enum.Enum):
|
||||
|
||||
|
||||
# Apply the __repr__ modification and __str__ fix to IntEnum
|
||||
class IntEnum(_enum.IntEnum):
|
||||
class IntEnum(_enum.IntEnum): # pylint: disable=invalid-slots
|
||||
"""Helper class for int enums where ``str(member)`` prints the value, but ``repr(member)``
|
||||
gives ``EnumName.MEMBER_NAME``.
|
||||
"""
|
||||
|
||||
@@ -26,19 +26,28 @@ Warning:
|
||||
the changelog.
|
||||
"""
|
||||
import warnings
|
||||
from typing import Type
|
||||
from typing import Type, Union
|
||||
|
||||
from telegram.warnings import PTBUserWarning
|
||||
|
||||
|
||||
def warn(message: str, category: Type[Warning] = PTBUserWarning, stacklevel: int = 0) -> None:
|
||||
def warn(
|
||||
message: Union[str, PTBUserWarning],
|
||||
category: Type[Warning] = PTBUserWarning,
|
||||
stacklevel: int = 0,
|
||||
) -> None:
|
||||
"""
|
||||
Helper function used as a shortcut for warning with default values.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
|
||||
Args:
|
||||
message (:obj:`str`): Specify the warnings message to pass to ``warnings.warn()``.
|
||||
message (:obj:`str` | :obj:`PTBUserWarning`): Specify the warnings message to pass to
|
||||
``warnings.warn()``.
|
||||
|
||||
.. versionchanged:: 21.2
|
||||
Now also accepts a :obj:`PTBUserWarning` instance.
|
||||
|
||||
category (:obj:`Type[Warning]`, optional): Specify the Warning class to pass to
|
||||
``warnings.warn()``. Defaults to :class:`telegram.warnings.PTBUserWarning`.
|
||||
stacklevel (:obj:`int`, optional): Specify the stacklevel to pass to ``warnings.warn()``.
|
||||
|
||||
@@ -23,10 +23,10 @@ inside warnings.py.
|
||||
|
||||
.. versionadded:: 20.2
|
||||
"""
|
||||
from typing import Any, Callable, Type
|
||||
from typing import Any, Callable, Type, Union
|
||||
|
||||
from telegram._utils.warnings import warn
|
||||
from telegram.warnings import PTBDeprecationWarning
|
||||
from telegram.warnings import PTBDeprecationWarning, PTBUserWarning
|
||||
|
||||
|
||||
def build_deprecation_warning_message(
|
||||
@@ -54,8 +54,9 @@ def warn_about_deprecated_arg_return_new_arg(
|
||||
deprecated_arg_name: str,
|
||||
new_arg_name: str,
|
||||
bot_api_version: str,
|
||||
ptb_version: str,
|
||||
stacklevel: int = 2,
|
||||
warn_callback: Callable[[str, Type[Warning], int], None] = warn,
|
||||
warn_callback: Callable[[Union[str, PTBUserWarning], Type[Warning], int], None] = warn,
|
||||
) -> Any:
|
||||
"""A helper function for the transition in API when argument is renamed.
|
||||
|
||||
@@ -80,10 +81,12 @@ def warn_about_deprecated_arg_return_new_arg(
|
||||
|
||||
if deprecated_arg:
|
||||
warn_callback(
|
||||
f"Bot API {bot_api_version} renamed the argument '{deprecated_arg_name}' to "
|
||||
f"'{new_arg_name}'.",
|
||||
PTBDeprecationWarning,
|
||||
stacklevel + 1,
|
||||
PTBDeprecationWarning(
|
||||
ptb_version,
|
||||
f"Bot API {bot_api_version} renamed the argument '{deprecated_arg_name}' to "
|
||||
f"'{new_arg_name}'.",
|
||||
),
|
||||
stacklevel=stacklevel + 1, # type: ignore[call-arg]
|
||||
)
|
||||
return deprecated_arg
|
||||
|
||||
@@ -94,6 +97,7 @@ def warn_about_deprecated_attr_in_property(
|
||||
deprecated_attr_name: str,
|
||||
new_attr_name: str,
|
||||
bot_api_version: str,
|
||||
ptb_version: str,
|
||||
stacklevel: int = 2,
|
||||
) -> None:
|
||||
"""A helper function for the transition in API when attribute is renamed. Call from properties.
|
||||
@@ -101,8 +105,10 @@ def warn_about_deprecated_attr_in_property(
|
||||
The properties replace deprecated attributes in classes and issue these deprecation warnings.
|
||||
"""
|
||||
warn(
|
||||
f"Bot API {bot_api_version} renamed the attribute '{deprecated_attr_name}' to "
|
||||
f"'{new_attr_name}'.",
|
||||
PTBDeprecationWarning,
|
||||
PTBDeprecationWarning(
|
||||
ptb_version,
|
||||
f"Bot API {bot_api_version} renamed the attribute '{deprecated_attr_name}' to "
|
||||
f"'{new_attr_name}'.",
|
||||
),
|
||||
stacklevel=stacklevel + 1,
|
||||
)
|
||||
|
||||
@@ -51,7 +51,7 @@ class Version(NamedTuple):
|
||||
|
||||
|
||||
__version_info__: Final[Version] = Version(
|
||||
major=21, minor=0, micro=0, releaselevel="final", serial=0
|
||||
major=21, minor=3, micro=0, releaselevel="final", serial=0
|
||||
)
|
||||
__version__: Final[str] = str(__version_info__)
|
||||
|
||||
|
||||
+183
-36
@@ -29,7 +29,7 @@ those classes.
|
||||
* Most of the constants in this module are grouped into enums.
|
||||
"""
|
||||
# TODO: Remove this when https://github.com/PyCQA/pylint/issues/6887 is resolved.
|
||||
# pylint: disable=invalid-enum-extension
|
||||
# pylint: disable=invalid-enum-extension,invalid-slots
|
||||
|
||||
__all__ = [
|
||||
"BOT_API_VERSION",
|
||||
@@ -37,6 +37,10 @@ __all__ = [
|
||||
"SUPPORTED_WEBHOOK_PORTS",
|
||||
"ZERO_DATE",
|
||||
"AccentColor",
|
||||
"BackgroundFillLimit",
|
||||
"BackgroundFillType",
|
||||
"BackgroundTypeLimit",
|
||||
"BackgroundTypeType",
|
||||
"BotCommandLimit",
|
||||
"BotCommandScopeType",
|
||||
"BotDescriptionLimit",
|
||||
@@ -142,7 +146,7 @@ class _AccentColor(NamedTuple):
|
||||
#: :data:`telegram.__bot_api_version_info__`.
|
||||
#:
|
||||
#: .. versionadded:: 20.0
|
||||
BOT_API_VERSION_INFO: Final[_BotAPIVersion] = _BotAPIVersion(major=7, minor=1)
|
||||
BOT_API_VERSION_INFO: Final[_BotAPIVersion] = _BotAPIVersion(major=7, minor=4)
|
||||
#: :obj:`str`: Telegram Bot API
|
||||
#: version supported by this version of `python-telegram-bot`. Also available as
|
||||
#: :data:`telegram.__bot_api_version__`.
|
||||
@@ -164,7 +168,8 @@ ZERO_DATE: Final[datetime.datetime] = datetime.datetime(1970, 1, 1, tzinfo=UTC)
|
||||
|
||||
|
||||
class AccentColor(Enum):
|
||||
"""This enum contains the available accent colors for :class:`telegram.Chat.accent_color_id`.
|
||||
"""This enum contains the available accent colors for
|
||||
:class:`telegram.ChatFullInfo.accent_color_id`.
|
||||
The members of this enum are named tuples with the following attributes:
|
||||
|
||||
- ``identifier`` (:obj:`int`): The identifier of the accent color.
|
||||
@@ -822,6 +827,46 @@ class ChatLimit(IntEnum):
|
||||
"""
|
||||
|
||||
|
||||
class BackgroundTypeLimit(IntEnum):
|
||||
"""This enum contains limitations for :class:`telegram.BackgroundTypeFill`,
|
||||
:class:`telegram.BackgroundTypeWallpaper` and :class:`telegram.BackgroundTypePattern`.
|
||||
The enum members of this enumeration are instances of :class:`int` and can be treated as such.
|
||||
|
||||
.. versionadded:: 21.2
|
||||
"""
|
||||
|
||||
__slots__ = ()
|
||||
|
||||
MAX_DIMMING = 100
|
||||
""":obj:`int`: Maximum value allowed for:
|
||||
|
||||
* :paramref:`~telegram.BackgroundTypeFill.dark_theme_dimming` parameter of
|
||||
:class:`telegram.BackgroundTypeFill`
|
||||
* :paramref:`~telegram.BackgroundTypeWallpaper.dark_theme_dimming` parameter of
|
||||
:class:`telegram.BackgroundTypeWallpaper`
|
||||
"""
|
||||
MAX_INTENSITY = 100
|
||||
""":obj:`int`: Maximum value allowed for :paramref:`~telegram.BackgroundTypePattern.intensity`
|
||||
parameter of :class:`telegram.BackgroundTypePattern`
|
||||
"""
|
||||
|
||||
|
||||
class BackgroundFillLimit(IntEnum):
|
||||
"""This enum contains limitations for :class:`telegram.BackgroundFillGradient`.
|
||||
The enum members of this enumeration are instances of :class:`int` and can be treated as such.
|
||||
|
||||
.. versionadded:: 21.2
|
||||
"""
|
||||
|
||||
__slots__ = ()
|
||||
|
||||
MAX_ROTATION_ANGLE = 359
|
||||
""":obj:`int`: Maximum value allowed for:
|
||||
:paramref:`~telegram.BackgroundFillGradient.rotation_angle` parameter of
|
||||
:class:`telegram.BackgroundFillGradient`
|
||||
"""
|
||||
|
||||
|
||||
class ChatMemberStatus(StringEnum):
|
||||
"""This enum contains the available states for :class:`telegram.ChatMember`. The enum
|
||||
members of this enumeration are instances of :class:`str` and can be treated as such.
|
||||
@@ -1427,6 +1472,21 @@ class LocationLimit(IntEnum):
|
||||
:meth:`telegram.Bot.send_location`
|
||||
"""
|
||||
|
||||
LIVE_PERIOD_FOREVER = int(hex(0x7FFFFFFF), 16)
|
||||
""":obj:`int`: Value for live locations that can be edited indefinitely. Passed in:
|
||||
|
||||
* :paramref:`~telegram.InlineQueryResultLocation.live_period` parameter of
|
||||
:class:`telegram.InlineQueryResultLocation`
|
||||
* :paramref:`~telegram.InputLocationMessageContent.live_period` parameter of
|
||||
:class:`telegram.InputLocationMessageContent`
|
||||
* :paramref:`~telegram.Bot.edit_message_live_location.live_period` parameter of
|
||||
:meth:`telegram.Bot.edit_message_live_location`
|
||||
* :paramref:`~telegram.Bot.send_location.live_period` parameter of
|
||||
:meth:`telegram.Bot.send_location`
|
||||
|
||||
.. versionadded:: 21.2
|
||||
"""
|
||||
|
||||
MIN_PROXIMITY_ALERT_RADIUS = 1
|
||||
""":obj:`int`: Minimum value allowed for:
|
||||
|
||||
@@ -1570,48 +1630,53 @@ class MessageEntityType(StringEnum):
|
||||
|
||||
__slots__ = ()
|
||||
|
||||
MENTION = "mention"
|
||||
""":obj:`str`: Message entities representing a mention."""
|
||||
HASHTAG = "hashtag"
|
||||
""":obj:`str`: Message entities representing a hashtag."""
|
||||
CASHTAG = "cashtag"
|
||||
""":obj:`str`: Message entities representing a cashtag."""
|
||||
PHONE_NUMBER = "phone_number"
|
||||
""":obj:`str`: Message entities representing a phone number."""
|
||||
BOT_COMMAND = "bot_command"
|
||||
""":obj:`str`: Message entities representing a bot command."""
|
||||
URL = "url"
|
||||
""":obj:`str`: Message entities representing a url."""
|
||||
EMAIL = "email"
|
||||
""":obj:`str`: Message entities representing a email."""
|
||||
BLOCKQUOTE = "blockquote"
|
||||
""":obj:`str`: Message entities representing a block quotation.
|
||||
|
||||
.. versionadded:: 20.8
|
||||
"""
|
||||
BOLD = "bold"
|
||||
""":obj:`str`: Message entities representing bold text."""
|
||||
ITALIC = "italic"
|
||||
""":obj:`str`: Message entities representing italic text."""
|
||||
BOT_COMMAND = "bot_command"
|
||||
""":obj:`str`: Message entities representing a bot command."""
|
||||
CASHTAG = "cashtag"
|
||||
""":obj:`str`: Message entities representing a cashtag."""
|
||||
CODE = "code"
|
||||
""":obj:`str`: Message entities representing monowidth string."""
|
||||
CUSTOM_EMOJI = "custom_emoji"
|
||||
""":obj:`str`: Message entities representing inline custom emoji stickers.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
EMAIL = "email"
|
||||
""":obj:`str`: Message entities representing a email."""
|
||||
EXPANDABLE_BLOCKQUOTE = "expandable_blockquote"
|
||||
""":obj:`str`: Message entities representing collapsed-by-default block quotation.
|
||||
|
||||
.. versionadded:: 21.3
|
||||
"""
|
||||
HASHTAG = "hashtag"
|
||||
""":obj:`str`: Message entities representing a hashtag."""
|
||||
ITALIC = "italic"
|
||||
""":obj:`str`: Message entities representing italic text."""
|
||||
MENTION = "mention"
|
||||
""":obj:`str`: Message entities representing a mention."""
|
||||
PHONE_NUMBER = "phone_number"
|
||||
""":obj:`str`: Message entities representing a phone number."""
|
||||
PRE = "pre"
|
||||
""":obj:`str`: Message entities representing monowidth block."""
|
||||
SPOILER = "spoiler"
|
||||
""":obj:`str`: Message entities representing spoiler text."""
|
||||
STRIKETHROUGH = "strikethrough"
|
||||
""":obj:`str`: Message entities representing strikethrough text."""
|
||||
TEXT_LINK = "text_link"
|
||||
""":obj:`str`: Message entities representing clickable text URLs."""
|
||||
TEXT_MENTION = "text_mention"
|
||||
""":obj:`str`: Message entities representing text mention for users without usernames."""
|
||||
UNDERLINE = "underline"
|
||||
""":obj:`str`: Message entities representing underline text."""
|
||||
STRIKETHROUGH = "strikethrough"
|
||||
""":obj:`str`: Message entities representing strikethrough text."""
|
||||
SPOILER = "spoiler"
|
||||
""":obj:`str`: Message entities representing spoiler text."""
|
||||
CUSTOM_EMOJI = "custom_emoji"
|
||||
""":obj:`str`: Message entities representing inline custom emoji stickers.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
BLOCKQUOTE = "blockquote"
|
||||
""":obj:`str`: Message entities representing a block quotation.
|
||||
|
||||
.. versionadded:: 20.8
|
||||
"""
|
||||
URL = "url"
|
||||
""":obj:`str`: Message entities representing a url."""
|
||||
|
||||
|
||||
class MessageLimit(IntEnum):
|
||||
@@ -1690,8 +1755,12 @@ class MessageOriginType(StringEnum):
|
||||
|
||||
|
||||
class MessageType(StringEnum):
|
||||
"""This enum contains the available types of :class:`telegram.Message`. The enum
|
||||
members of this enumeration are instances of :class:`str` and can be treated as such.
|
||||
"""This enum contains the available types of :class:`telegram.Message`. Here, a "type" means
|
||||
a kind of message that is visually distinct from other kinds of messages in the Telegram app.
|
||||
In particular, auxiliary attributes that can be present for multiple types of messages are
|
||||
not considered in this enumeration.
|
||||
|
||||
The enum members of this enumeration are instances of :class:`str` and can be treated as such.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
@@ -1710,6 +1779,11 @@ class MessageType(StringEnum):
|
||||
|
||||
.. versionadded:: 21.0
|
||||
"""
|
||||
BUSINESS_CONNECTION_ID = "business_connection_id"
|
||||
""":obj:`str`: Messages with :attr:`telegram.Message.business_connection_id`.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
"""
|
||||
CHANNEL_CHAT_CREATED = "channel_chat_created"
|
||||
""":obj:`str`: Messages with :attr:`telegram.Message.channel_chat_created`."""
|
||||
CHAT_SHARED = "chat_shared"
|
||||
@@ -1717,6 +1791,11 @@ class MessageType(StringEnum):
|
||||
|
||||
.. versionadded:: 20.8
|
||||
"""
|
||||
CHAT_BACKGROUND_SET = "chat_background_set"
|
||||
""":obj:`str`: Messages with :attr:`telegram.Message.chat_background_set`.
|
||||
|
||||
.. versionadded:: 21.2
|
||||
"""
|
||||
CONNECTED_WEBSITE = "connected_website"
|
||||
""":obj:`str`: Messages with :attr:`telegram.Message.connected_website`."""
|
||||
CONTACT = "contact"
|
||||
@@ -1727,6 +1806,10 @@ class MessageType(StringEnum):
|
||||
""":obj:`str`: Messages with :attr:`telegram.Message.dice`."""
|
||||
DOCUMENT = "document"
|
||||
""":obj:`str`: Messages with :attr:`telegram.Message.document`."""
|
||||
EFFECT_ID = "effect_id"
|
||||
""":obj:`str`: Messages with :attr:`telegram.Message.effect_id`.
|
||||
|
||||
.. versionadded:: 21.3"""
|
||||
FORUM_TOPIC_CREATED = "forum_topic_created"
|
||||
""":obj:`str`: Messages with :attr:`telegram.Message.forum_topic_created`.
|
||||
|
||||
@@ -1817,6 +1900,11 @@ class MessageType(StringEnum):
|
||||
|
||||
.. versionadded:: 21.0
|
||||
"""
|
||||
SENDER_BUSINESS_BOT = "sender_business_bot"
|
||||
""":obj:`str`: Messages with :attr:`telegram.Message.sender_business_bot`.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
"""
|
||||
STICKER = "sticker"
|
||||
""":obj:`str`: Messages with :attr:`telegram.Message.sticker`."""
|
||||
STORY = "story"
|
||||
@@ -1881,7 +1969,7 @@ class PollingLimit(IntEnum):
|
||||
|
||||
class ProfileAccentColor(Enum):
|
||||
"""This enum contains the available accent colors for
|
||||
:class:`telegram.Chat.profile_accent_color_id`.
|
||||
:class:`telegram.ChatFullInfo.profile_accent_color_id`.
|
||||
The members of this enum are named tuples with the following attributes:
|
||||
|
||||
- ``identifier`` (:obj:`int`): The identifier of the accent color.
|
||||
@@ -2312,6 +2400,9 @@ class StickerSetLimit(IntEnum):
|
||||
MAX_ANIMATED_STICKERS = 50
|
||||
""":obj:`int`: Maximum number of stickers allowed in an animated or video sticker set, as given
|
||||
in :meth:`telegram.Bot.add_sticker_to_set`.
|
||||
|
||||
.. deprecated:: 21.1
|
||||
The animated sticker limit is now 120, the same as :attr:`MAX_STATIC_STICKERS`.
|
||||
"""
|
||||
MAX_STATIC_STICKERS = 120
|
||||
""":obj:`int`: Maximum number of stickers allowed in a static sticker set, as given in
|
||||
@@ -2504,6 +2595,26 @@ class UpdateType(StringEnum):
|
||||
|
||||
.. versionadded:: 20.8
|
||||
"""
|
||||
BUSINESS_CONNECTION = "business_connection"
|
||||
""":obj:`str`: Updates with :attr:`telegram.Update.business_connection`.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
"""
|
||||
BUSINESS_MESSAGE = "business_message"
|
||||
""":obj:`str`: Updates with :attr:`telegram.Update.business_message`.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
"""
|
||||
EDITED_BUSINESS_MESSAGE = "edited_business_message"
|
||||
""":obj:`str`: Updates with :attr:`telegram.Update.edited_business_message`.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
"""
|
||||
DELETED_BUSINESS_MESSAGES = "deleted_business_messages"
|
||||
""":obj:`str`: Updates with :attr:`telegram.Update.deleted_business_messages`.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
"""
|
||||
|
||||
|
||||
class InvoiceLimit(IntEnum):
|
||||
@@ -2841,3 +2952,39 @@ class ReactionEmoji(StringEnum):
|
||||
""":obj:`str`: Woman Shrugging"""
|
||||
POUTING_FACE = "😡"
|
||||
""":obj:`str`: Pouting face"""
|
||||
|
||||
|
||||
class BackgroundTypeType(StringEnum):
|
||||
"""This enum contains the available types of :class:`telegram.BackgroundType`. The enum
|
||||
members of this enumeration are instances of :class:`str` and can be treated as such.
|
||||
|
||||
.. versionadded:: 21.2
|
||||
"""
|
||||
|
||||
__slots__ = ()
|
||||
|
||||
FILL = "fill"
|
||||
""":obj:`str`: A :class:`telegram.BackgroundType` with fill background."""
|
||||
WALLPAPER = "wallpaper"
|
||||
""":obj:`str`: A :class:`telegram.BackgroundType` with wallpaper background."""
|
||||
PATTERN = "pattern"
|
||||
""":obj:`str`: A :class:`telegram.BackgroundType` with pattern background."""
|
||||
CHAT_THEME = "chat_theme"
|
||||
""":obj:`str`: A :class:`telegram.BackgroundType` with chat_theme background."""
|
||||
|
||||
|
||||
class BackgroundFillType(StringEnum):
|
||||
"""This enum contains the available types of :class:`telegram.BackgroundFill`. The enum
|
||||
members of this enumeration are instances of :class:`str` and can be treated as such.
|
||||
|
||||
.. versionadded:: 21.2
|
||||
"""
|
||||
|
||||
__slots__ = ()
|
||||
|
||||
SOLID = "solid"
|
||||
""":obj:`str`: A :class:`telegram.BackgroundFill` with solid fill."""
|
||||
GRADIENT = "gradient"
|
||||
""":obj:`str`: A :class:`telegram.BackgroundFill` with gradient fill."""
|
||||
FREEFORM_GRADIENT = "freeform_gradient"
|
||||
""":obj:`str`: A :class:`telegram.BackgroundFill` with freeform_gradient fill."""
|
||||
|
||||
@@ -27,6 +27,8 @@ __all__ = (
|
||||
"BasePersistence",
|
||||
"BaseRateLimiter",
|
||||
"BaseUpdateProcessor",
|
||||
"BusinessConnectionHandler",
|
||||
"BusinessMessagesDeletedHandler",
|
||||
"CallbackContext",
|
||||
"CallbackDataCache",
|
||||
"CallbackQueryHandler",
|
||||
@@ -75,6 +77,8 @@ from ._defaults import Defaults
|
||||
from ._dictpersistence import DictPersistence
|
||||
from ._extbot import ExtBot
|
||||
from ._handlers.basehandler import BaseHandler
|
||||
from ._handlers.businessconnectionhandler import BusinessConnectionHandler
|
||||
from ._handlers.businessmessagesdeletedhandler import BusinessMessagesDeletedHandler
|
||||
from ._handlers.callbackqueryhandler import CallbackQueryHandler
|
||||
from ._handlers.chatboosthandler import ChatBoostHandler
|
||||
from ._handlers.chatjoinrequesthandler import ChatJoinRequestHandler
|
||||
|
||||
@@ -208,7 +208,7 @@ class AIORateLimiter(BaseRateLimiter[int]):
|
||||
callback: Callable[..., Coroutine[Any, Any, Union[bool, JSONDict, List[JSONDict]]]],
|
||||
args: Any,
|
||||
kwargs: Dict[str, Any],
|
||||
endpoint: str,
|
||||
endpoint: str, # noqa: ARG002
|
||||
data: Dict[str, Any],
|
||||
rate_limit_args: Optional[int],
|
||||
) -> Union[bool, JSONDict, List[JSONDict]]:
|
||||
|
||||
+159
-86
@@ -75,6 +75,8 @@ from telegram.ext._utils.types import BD, BT, CCT, CD, JQ, RT, UD, ConversationK
|
||||
from telegram.warnings import PTBDeprecationWarning
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from socket import socket
|
||||
|
||||
from telegram import Message
|
||||
from telegram.ext import ConversationHandler, JobQueue
|
||||
from telegram.ext._applicationbuilder import InitApplicationBuilder
|
||||
@@ -363,6 +365,7 @@ class Application(Generic[BT, CCT, UD, CD, BD, JQ], AsyncContextManager["Applica
|
||||
self.__update_persistence_event = asyncio.Event()
|
||||
self.__update_persistence_lock = asyncio.Lock()
|
||||
self.__create_task_tasks: Set[asyncio.Task] = set() # Used for awaiting tasks upon exit
|
||||
self.__stop_running_marker = asyncio.Event()
|
||||
|
||||
async def __aenter__(self: _AppType) -> _AppType: # noqa: PYI019
|
||||
"""|async_context_manager| :meth:`initializes <initialize>` the App.
|
||||
@@ -514,6 +517,7 @@ class Application(Generic[BT, CCT, UD, CD, BD, JQ], AsyncContextManager["Applica
|
||||
await self._add_ch_to_persistence(handler)
|
||||
|
||||
self._initialized = True
|
||||
self.__stop_running_marker.clear()
|
||||
|
||||
async def _add_ch_to_persistence(self, handler: "ConversationHandler") -> None:
|
||||
self._conversation_handler_conversations.update(
|
||||
@@ -668,14 +672,26 @@ class Application(Generic[BT, CCT, UD, CD, BD, JQ], AsyncContextManager["Applica
|
||||
raise RuntimeError("This Application is not running!")
|
||||
|
||||
self._running = False
|
||||
self.__stop_running_marker.clear()
|
||||
_LOGGER.info("Application is stopping. This might take a moment.")
|
||||
|
||||
# Stop listening for new updates and handle all pending ones
|
||||
await self.update_queue.put(_STOP_SIGNAL)
|
||||
_LOGGER.debug("Waiting for update_queue to join")
|
||||
await self.update_queue.join()
|
||||
if self.__update_fetcher_task:
|
||||
await self.__update_fetcher_task
|
||||
if self.__update_fetcher_task.done():
|
||||
try:
|
||||
self.__update_fetcher_task.result()
|
||||
except BaseException as exc:
|
||||
_LOGGER.critical(
|
||||
"Fetching updates was aborted due to %r. Suppressing "
|
||||
"exception to ensure graceful shutdown.",
|
||||
exc,
|
||||
exc_info=True,
|
||||
)
|
||||
else:
|
||||
await self.update_queue.put(_STOP_SIGNAL)
|
||||
_LOGGER.debug("Waiting for update_queue to join")
|
||||
await self.update_queue.join()
|
||||
await self.__update_fetcher_task
|
||||
_LOGGER.debug("Application stopped fetching of updates.")
|
||||
|
||||
if self._job_queue:
|
||||
@@ -701,17 +717,36 @@ class Application(Generic[BT, CCT, UD, CD, BD, JQ], AsyncContextManager["Applica
|
||||
shutdown of the application, i.e. the methods listed in :attr:`run_polling` and
|
||||
:attr:`run_webhook` will still be executed.
|
||||
|
||||
This method can also be called within :meth:`post_init`. This allows for a graceful,
|
||||
early shutdown of the application if some condition is met (e.g., a database connection
|
||||
could not be established).
|
||||
|
||||
Note:
|
||||
If the application is not running, this method does nothing.
|
||||
If the application is not running and this method is not called within
|
||||
:meth:`post_init`, this method does nothing.
|
||||
|
||||
Warning:
|
||||
This method is designed to for use in combination with :meth:`run_polling` or
|
||||
:meth:`run_webhook`. Using this method in combination with a custom logic for starting
|
||||
and stopping the application is not guaranteed to work as expected. Use at your own
|
||||
risk.
|
||||
|
||||
.. versionadded:: 20.5
|
||||
|
||||
.. versionchanged:: 21.2
|
||||
Added support for calling within :meth:`post_init`.
|
||||
"""
|
||||
if self.running:
|
||||
# This works because `__run` is using `loop.run_forever()`. If that changes, this
|
||||
# method needs to be adapted.
|
||||
asyncio.get_running_loop().stop()
|
||||
else:
|
||||
_LOGGER.debug("Application is not running, stop_running() does nothing.")
|
||||
self.__stop_running_marker.set()
|
||||
if not self._initialized:
|
||||
_LOGGER.debug(
|
||||
"Application is not running and not initialized. `stop_running()` likely has "
|
||||
"no effect."
|
||||
)
|
||||
|
||||
def run_polling(
|
||||
self,
|
||||
@@ -731,9 +766,7 @@ class Application(Generic[BT, CCT, UD, CD, BD, JQ], AsyncContextManager["Applica
|
||||
polling updates from Telegram using :meth:`telegram.ext.Updater.start_polling` and
|
||||
a graceful shutdown of the app on exit.
|
||||
|
||||
The app will shut down when :exc:`KeyboardInterrupt` or :exc:`SystemExit` is raised.
|
||||
On unix, the app will also shut down on receiving the signals specified by
|
||||
:paramref:`stop_signals`.
|
||||
|app_run_shutdown| :paramref:`stop_signals`.
|
||||
|
||||
The order of execution by :meth:`run_polling` is roughly as follows:
|
||||
|
||||
@@ -824,9 +857,11 @@ class Application(Generic[BT, CCT, UD, CD, BD, JQ], AsyncContextManager["Applica
|
||||
|
||||
if (read_timeout, write_timeout, connect_timeout, pool_timeout) != ((DEFAULT_NONE,) * 4):
|
||||
warn(
|
||||
"Setting timeouts via `Application.run_polling` is deprecated. "
|
||||
"Please use `ApplicationBuilder.get_updates_*_timeout` instead.",
|
||||
PTBDeprecationWarning,
|
||||
PTBDeprecationWarning(
|
||||
"20.6",
|
||||
"Setting timeouts via `Application.run_polling` is deprecated. "
|
||||
"Please use `ApplicationBuilder.get_updates_*_timeout` instead.",
|
||||
),
|
||||
stacklevel=2,
|
||||
)
|
||||
|
||||
@@ -866,15 +901,13 @@ class Application(Generic[BT, CCT, UD, CD, BD, JQ], AsyncContextManager["Applica
|
||||
close_loop: bool = True,
|
||||
stop_signals: ODVInput[Sequence[int]] = DEFAULT_NONE,
|
||||
secret_token: Optional[str] = None,
|
||||
unix: Optional[Union[str, Path]] = None,
|
||||
unix: Optional[Union[str, Path, "socket"]] = None,
|
||||
) -> None:
|
||||
"""Convenience method that takes care of initializing and starting the app,
|
||||
listening for updates from Telegram using :meth:`telegram.ext.Updater.start_webhook` and
|
||||
a graceful shutdown of the app on exit.
|
||||
|
||||
The app will shut down when :exc:`KeyboardInterrupt` or :exc:`SystemExit` is raised.
|
||||
On unix, the app will also shut down on receiving the signals specified by
|
||||
:paramref:`stop_signals`.
|
||||
|app_run_shutdown| :paramref:`stop_signals`.
|
||||
|
||||
If :paramref:`cert`
|
||||
and :paramref:`key` are not provided, the webhook will be started directly on
|
||||
@@ -959,8 +992,17 @@ class Application(Generic[BT, CCT, UD, CD, BD, JQ], AsyncContextManager["Applica
|
||||
header isn't set or it is set to a wrong token.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
unix (:class:`pathlib.Path` | :obj:`str`, optional): Path to the unix socket file. Path
|
||||
does not need to exist, in which case the file will be created.
|
||||
unix (:class:`pathlib.Path` | :obj:`str` | :class:`socket.socket`, optional): Can be
|
||||
either:
|
||||
|
||||
* the path to the unix socket file as :class:`pathlib.Path` or :obj:`str`. This
|
||||
will be passed to `tornado.netutil.bind_unix_socket <https://www.tornadoweb.org/
|
||||
en/stable/netutil.html#tornado.netutil.bind_unix_socket>`_ to create the socket.
|
||||
If the Path does not exist, the file will be created.
|
||||
|
||||
* or the socket itself. This option allows you to e.g. restrict the permissions of
|
||||
the socket for improved security. Note that you need to pass the correct family,
|
||||
type and socket options yourself.
|
||||
|
||||
Caution:
|
||||
This parameter is a replacement for the default TCP bind. Therefore, it is
|
||||
@@ -969,6 +1011,8 @@ class Application(Generic[BT, CCT, UD, CD, BD, JQ], AsyncContextManager["Applica
|
||||
appropriate :paramref:`webhook_url`.
|
||||
|
||||
.. versionadded:: 20.8
|
||||
.. versionchanged:: 21.1
|
||||
Added support to pass a socket instance itself.
|
||||
"""
|
||||
if not self.updater:
|
||||
raise RuntimeError(
|
||||
@@ -1025,25 +1069,28 @@ class Application(Generic[BT, CCT, UD, CD, BD, JQ], AsyncContextManager["Applica
|
||||
loop.run_until_complete(self.initialize())
|
||||
if self.post_init:
|
||||
loop.run_until_complete(self.post_init(self))
|
||||
if self.__stop_running_marker.is_set():
|
||||
_LOGGER.info("Application received stop signal via `stop_running`. Shutting down.")
|
||||
return
|
||||
loop.run_until_complete(updater_coroutine) # one of updater.start_webhook/polling
|
||||
loop.run_until_complete(self.start())
|
||||
loop.run_forever()
|
||||
except (KeyboardInterrupt, SystemExit):
|
||||
_LOGGER.debug("Application received stop signal. Shutting down.")
|
||||
except Exception as exc:
|
||||
# In case the coroutine wasn't awaited, we don't need to bother the user with a warning
|
||||
updater_coroutine.close()
|
||||
raise exc
|
||||
finally:
|
||||
# We arrive here either by catching the exceptions above or if the loop gets stopped
|
||||
# In case the coroutine wasn't awaited, we don't need to bother the user with a warning
|
||||
updater_coroutine.close()
|
||||
|
||||
try:
|
||||
# Mypy doesn't know that we already check if updater is None
|
||||
if self.updater.running: # type: ignore[union-attr]
|
||||
loop.run_until_complete(self.updater.stop()) # type: ignore[union-attr]
|
||||
if self.running:
|
||||
loop.run_until_complete(self.stop())
|
||||
if self.post_stop:
|
||||
loop.run_until_complete(self.post_stop(self))
|
||||
# post_stop should be called only if stop was called!
|
||||
if self.post_stop:
|
||||
loop.run_until_complete(self.post_stop(self))
|
||||
loop.run_until_complete(self.shutdown())
|
||||
if self.post_shutdown:
|
||||
loop.run_until_complete(self.post_shutdown(self))
|
||||
@@ -1138,9 +1185,11 @@ class Application(Generic[BT, CCT, UD, CD, BD, JQ], AsyncContextManager["Applica
|
||||
# Generator-based coroutines are not supported in Python 3.12+
|
||||
if sys.version_info < (3, 12) and isinstance(coroutine, Generator):
|
||||
warn(
|
||||
"Generator-based coroutines are deprecated in create_task and will not work"
|
||||
" in Python 3.12+",
|
||||
category=PTBDeprecationWarning,
|
||||
PTBDeprecationWarning(
|
||||
"20.4",
|
||||
"Generator-based coroutines are deprecated in create_task and will not"
|
||||
" work in Python 3.12+",
|
||||
),
|
||||
)
|
||||
return await asyncio.create_task(coroutine)
|
||||
# If user uses generator in python 3.12+, Exception will happen and we cannot do
|
||||
@@ -1172,45 +1221,44 @@ class Application(Generic[BT, CCT, UD, CD, BD, JQ], AsyncContextManager["Applica
|
||||
finally:
|
||||
self._mark_for_persistence_update(update=update)
|
||||
|
||||
async def _update_fetcher(self) -> None:
|
||||
async def __update_fetcher(self) -> None:
|
||||
# Continuously fetch updates from the queue. Exit only once the signal object is found.
|
||||
while True:
|
||||
try:
|
||||
update = await self.update_queue.get()
|
||||
update = await self.update_queue.get()
|
||||
|
||||
if update is _STOP_SIGNAL:
|
||||
_LOGGER.debug("Dropping pending updates")
|
||||
while not self.update_queue.empty():
|
||||
self.update_queue.task_done()
|
||||
if update is _STOP_SIGNAL:
|
||||
# For the _STOP_SIGNAL
|
||||
self.update_queue.task_done()
|
||||
return
|
||||
|
||||
# For the _STOP_SIGNAL
|
||||
self.update_queue.task_done()
|
||||
return
|
||||
_LOGGER.debug("Processing update %s", update)
|
||||
|
||||
_LOGGER.debug("Processing update %s", update)
|
||||
|
||||
if self._update_processor.max_concurrent_updates > 1:
|
||||
# We don't await the below because it has to be run concurrently
|
||||
self.create_task(
|
||||
self.__process_update_wrapper(update),
|
||||
update=update,
|
||||
name=f"Application:{self.bot.id}:process_concurrent_update",
|
||||
)
|
||||
else:
|
||||
await self.__process_update_wrapper(update)
|
||||
|
||||
except asyncio.CancelledError:
|
||||
# This may happen if the application is manually run via application.start() and
|
||||
# then a KeyboardInterrupt is sent. We must prevent this loop to die since
|
||||
# application.stop() will wait for it's clean shutdown.
|
||||
_LOGGER.warning(
|
||||
"Fetching updates got a asyncio.CancelledError. Ignoring as this task may only"
|
||||
"be closed via `Application.stop`."
|
||||
if self._update_processor.max_concurrent_updates > 1:
|
||||
# We don't await the below because it has to be run concurrently
|
||||
self.create_task(
|
||||
self.__process_update_wrapper(update),
|
||||
update=update,
|
||||
name=f"Application:{self.bot.id}:process_concurrent_update",
|
||||
)
|
||||
else:
|
||||
await self.__process_update_wrapper(update)
|
||||
|
||||
async def _update_fetcher(self) -> None:
|
||||
try:
|
||||
await self.__update_fetcher()
|
||||
finally:
|
||||
while not self.update_queue.empty():
|
||||
_LOGGER.debug("Dropping pending update: %s", self.update_queue.get_nowait())
|
||||
with contextlib.suppress(ValueError):
|
||||
# Since we're shutting down here, it's not too bad if we call task_done
|
||||
# on an empty queue
|
||||
self.update_queue.task_done()
|
||||
|
||||
async def __process_update_wrapper(self, update: object) -> None:
|
||||
await self._update_processor.process_update(update, self.process_update(update))
|
||||
self.update_queue.task_done()
|
||||
try:
|
||||
await self._update_processor.process_update(update, self.process_update(update))
|
||||
finally:
|
||||
self.update_queue.task_done()
|
||||
|
||||
async def process_update(self, update: object) -> None:
|
||||
"""Processes a single update and marks the update to be updated by the persistence later.
|
||||
@@ -1239,30 +1287,43 @@ class Application(Generic[BT, CCT, UD, CD, BD, JQ], AsyncContextManager["Applica
|
||||
try:
|
||||
for handler in handlers:
|
||||
check = handler.check_update(update) # Should the handler handle this update?
|
||||
if not (check is None or check is False): # if yes,
|
||||
if not context: # build a context if not already built
|
||||
context = self.context_types.context.from_update(update, self)
|
||||
await context.refresh_data()
|
||||
coroutine: Coroutine = handler.handle_update(update, self, check, context)
|
||||
if check is None or check is False:
|
||||
continue
|
||||
|
||||
if not handler.block or ( # if handler is running with block=False,
|
||||
handler.block is DEFAULT_TRUE
|
||||
and isinstance(self.bot, ExtBot)
|
||||
and self.bot.defaults
|
||||
and not self.bot.defaults.block
|
||||
):
|
||||
self.create_task(
|
||||
coroutine,
|
||||
update=update,
|
||||
name=(
|
||||
f"Application:{self.bot.id}:process_update_non_blocking"
|
||||
f":{handler}"
|
||||
if not context: # build a context if not already built
|
||||
try:
|
||||
context = self.context_types.context.from_update(update, self)
|
||||
except Exception as exc:
|
||||
_LOGGER.critical(
|
||||
(
|
||||
"Error while building CallbackContext for update %s. "
|
||||
"Update will not be processed."
|
||||
),
|
||||
update,
|
||||
exc_info=exc,
|
||||
)
|
||||
else:
|
||||
any_blocking = True
|
||||
await coroutine
|
||||
break # Only a max of 1 handler per group is handled
|
||||
return
|
||||
await context.refresh_data()
|
||||
coroutine: Coroutine = handler.handle_update(update, self, check, context)
|
||||
|
||||
if not handler.block or ( # if handler is running with block=False,
|
||||
handler.block is DEFAULT_TRUE
|
||||
and isinstance(self.bot, ExtBot)
|
||||
and self.bot.defaults
|
||||
and not self.bot.defaults.block
|
||||
):
|
||||
self.create_task(
|
||||
coroutine,
|
||||
update=update,
|
||||
name=(
|
||||
f"Application:{self.bot.id}:process_update_non_blocking"
|
||||
f":{handler}"
|
||||
),
|
||||
)
|
||||
else:
|
||||
any_blocking = True
|
||||
await coroutine
|
||||
break # Only a max of 1 handler per group is handled
|
||||
|
||||
# Stop processing with any other handler.
|
||||
except ApplicationHandlerStop:
|
||||
@@ -1796,13 +1857,25 @@ class Application(Generic[BT, CCT, UD, CD, BD, JQ], AsyncContextManager["Applica
|
||||
callback,
|
||||
block,
|
||||
) in self.error_handlers.items():
|
||||
context = self.context_types.context.from_error(
|
||||
update=update,
|
||||
error=error,
|
||||
application=self,
|
||||
job=job,
|
||||
coroutine=coroutine,
|
||||
)
|
||||
try:
|
||||
context = self.context_types.context.from_error(
|
||||
update=update,
|
||||
error=error,
|
||||
application=self,
|
||||
job=job,
|
||||
coroutine=coroutine,
|
||||
)
|
||||
except Exception as exc:
|
||||
_LOGGER.critical(
|
||||
(
|
||||
"Error while building CallbackContext for exception %s. "
|
||||
"Exception will not be processed by error handlers."
|
||||
),
|
||||
error,
|
||||
exc_info=exc,
|
||||
)
|
||||
return False
|
||||
|
||||
if not block or ( # If error handler has `block=False`, create a Task to run cb
|
||||
block is DEFAULT_TRUE
|
||||
and isinstance(self.bot, ExtBot)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user