mirror of
https://github.com/python-telegram-bot/python-telegram-bot.git
synced 2026-06-19 23:55:29 +00:00
Compare commits
35 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 |
@@ -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@v2.0.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.3.5'
|
||||
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.3.0
|
||||
rev: 24.4.2
|
||||
hooks:
|
||||
- id: black
|
||||
args:
|
||||
@@ -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.9.0
|
||||
rev: v1.10.0
|
||||
hooks:
|
||||
- id: mypy
|
||||
name: mypy-ptb
|
||||
|
||||
@@ -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>`_
|
||||
|
||||
+105
@@ -4,6 +4,111 @@
|
||||
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
|
||||
==============
|
||||
|
||||
|
||||
+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.2-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.2** 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.2-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.2** 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
-3
@@ -20,9 +20,13 @@ author = "Leandro Toledo"
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = "21.1" # 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.1" # 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
|
||||
|
||||
@@ -369,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
|
||||
|
||||
|
||||
@@ -28,6 +28,16 @@ Available Types
|
||||
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
|
||||
@@ -36,6 +46,7 @@ Available Types
|
||||
telegram.chatboostsourcegiveaway
|
||||
telegram.chatboostsourcepremium
|
||||
telegram.chatboostupdated
|
||||
telegram.chatfullinfo
|
||||
telegram.chatinvitelink
|
||||
telegram.chatjoinrequest
|
||||
telegram.chatlocation
|
||||
@@ -77,6 +88,7 @@ Available Types
|
||||
telegram.inputmediadocument
|
||||
telegram.inputmediaphoto
|
||||
telegram.inputmediavideo
|
||||
telegram.inputpolloption
|
||||
telegram.inputsticker
|
||||
telegram.keyboardbutton
|
||||
telegram.keyboardbuttonpolltype
|
||||
|
||||
@@ -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:
|
||||
@@ -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 @@
|
||||
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 @@
|
||||
.. |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
|
||||
@@ -81,3 +81,9 @@
|
||||
.. |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", "W"]
|
||||
"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
|
||||
|
||||
|
||||
+53
-1
@@ -22,6 +22,15 @@ __author__ = "devs@python-telegram-bot.org"
|
||||
__all__ = (
|
||||
"Animation",
|
||||
"Audio",
|
||||
"BackgroundFill",
|
||||
"BackgroundFillFreeformGradient",
|
||||
"BackgroundFillGradient",
|
||||
"BackgroundFillSolid",
|
||||
"BackgroundType",
|
||||
"BackgroundTypeChatTheme",
|
||||
"BackgroundTypeFill",
|
||||
"BackgroundTypePattern",
|
||||
"BackgroundTypeWallpaper",
|
||||
"Birthdate",
|
||||
"Bot",
|
||||
"BotCommand",
|
||||
@@ -46,6 +55,7 @@ __all__ = (
|
||||
"CallbackQuery",
|
||||
"Chat",
|
||||
"ChatAdministratorRights",
|
||||
"ChatBackground",
|
||||
"ChatBoost",
|
||||
"ChatBoostAdded",
|
||||
"ChatBoostRemoved",
|
||||
@@ -54,6 +64,7 @@ __all__ = (
|
||||
"ChatBoostSourceGiveaway",
|
||||
"ChatBoostSourcePremium",
|
||||
"ChatBoostUpdated",
|
||||
"ChatFullInfo",
|
||||
"ChatInviteLink",
|
||||
"ChatJoinRequest",
|
||||
"ChatLocation",
|
||||
@@ -131,6 +142,7 @@ __all__ = (
|
||||
"InputMediaPhoto",
|
||||
"InputMediaVideo",
|
||||
"InputMessageContent",
|
||||
"InputPollOption",
|
||||
"InputSticker",
|
||||
"InputTextMessageContent",
|
||||
"InputVenueMessageContent",
|
||||
@@ -230,6 +242,7 @@ __all__ = (
|
||||
"warnings",
|
||||
)
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from . import _version, constants, error, helpers, request, warnings
|
||||
from ._birthdate import Birthdate
|
||||
@@ -258,6 +271,18 @@ from ._business import (
|
||||
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,
|
||||
@@ -269,6 +294,7 @@ from ._chatboost import (
|
||||
ChatBoostUpdated,
|
||||
UserChatBoosts,
|
||||
)
|
||||
from ._chatfullinfo import ChatFullInfo
|
||||
from ._chatinvitelink import ChatInviteLink
|
||||
from ._chatjoinrequest import ChatJoinRequest
|
||||
from ._chatlocation import ChatLocation
|
||||
@@ -403,7 +429,7 @@ 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
|
||||
@@ -417,6 +443,7 @@ 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,
|
||||
@@ -450,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,
|
||||
)
|
||||
|
||||
+10
-6
@@ -17,7 +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 an object that represents a Telegram Birthday."""
|
||||
from datetime import datetime
|
||||
from datetime import date
|
||||
from typing import Optional
|
||||
|
||||
from telegram._telegramobject import TelegramObject
|
||||
@@ -26,7 +26,7 @@ from telegram._utils.types import JSONDict
|
||||
|
||||
class Birthdate(TelegramObject):
|
||||
"""
|
||||
This object represents a user's birthday.
|
||||
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.
|
||||
@@ -70,19 +70,23 @@ class Birthdate(TelegramObject):
|
||||
|
||||
self._freeze()
|
||||
|
||||
def to_date(self, year: Optional[int] = None) -> datetime:
|
||||
"""Return the birthdate as a datetime object.
|
||||
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.datetime`: The birthdate as a datetime object.
|
||||
: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 datetime(year or self.year, self.month, self.day) # type: ignore[arg-type]
|
||||
return date(year or self.year, self.month, self.day) # type: ignore[arg-type]
|
||||
|
||||
+279
-74
@@ -58,9 +58,9 @@ from telegram._botcommandscope import BotCommandScope
|
||||
from telegram._botdescription import BotDescription, BotShortDescription
|
||||
from telegram._botname import BotName
|
||||
from telegram._business import BusinessConnection
|
||||
from telegram._chat import Chat
|
||||
from telegram._chatadministratorrights import ChatAdministratorRights
|
||||
from telegram._chatboost import UserChatBoosts
|
||||
from telegram._chatfullinfo import ChatFullInfo
|
||||
from telegram._chatinvitelink import ChatInviteLink
|
||||
from telegram._chatmember import ChatMember
|
||||
from telegram._chatpermissions import ChatPermissions
|
||||
@@ -84,7 +84,7 @@ from telegram._inline.inlinequeryresultsbutton import InlineQueryResultsButton
|
||||
from telegram._menubutton import MenuButton
|
||||
from telegram._message import Message
|
||||
from telegram._messageid import MessageId
|
||||
from telegram._poll import Poll
|
||||
from telegram._poll import InputPollOption, Poll
|
||||
from telegram._reaction import ReactionType, ReactionTypeCustomEmoji, ReactionTypeEmoji
|
||||
from telegram._reply import ReplyParameters
|
||||
from telegram._sentwebappmessage import SentWebAppMessage
|
||||
@@ -524,7 +524,10 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
|
||||
@classmethod
|
||||
def _warn(
|
||||
cls, message: str, category: Type[Warning] = PTBUserWarning, stacklevel: int = 0
|
||||
cls,
|
||||
message: Union[str, PTBUserWarning],
|
||||
category: Type[Warning] = PTBUserWarning,
|
||||
stacklevel: int = 0,
|
||||
) -> None:
|
||||
"""Convenience method to issue a warning. This method is here mostly to make it easier
|
||||
for ExtBot to add 1 level to all warning calls.
|
||||
@@ -669,6 +672,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
link_preview_options: ODVInput["LinkPreviewOptions"] = None,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
*,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
@@ -708,7 +712,9 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
data["disable_notification"] = disable_notification
|
||||
data["protect_content"] = protect_content
|
||||
data["parse_mode"] = parse_mode
|
||||
data["reply_parameters"] = reply_parameters
|
||||
|
||||
if reply_parameters is not None:
|
||||
data["reply_parameters"] = reply_parameters
|
||||
|
||||
if link_preview_options is not None:
|
||||
data["link_preview_options"] = link_preview_options
|
||||
@@ -728,6 +734,9 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
if business_connection_id is not None:
|
||||
data["business_connection_id"] = business_connection_id
|
||||
|
||||
if message_effect_id is not None:
|
||||
data["message_effect_id"] = message_effect_id
|
||||
|
||||
result = await self._post(
|
||||
endpoint,
|
||||
data,
|
||||
@@ -837,7 +846,6 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
f"Please use 'Bot.{endpoint}' instead of "
|
||||
f"'Bot.do_api_request(\"{endpoint}\", ...)'"
|
||||
),
|
||||
PTBDeprecationWarning,
|
||||
stacklevel=2,
|
||||
)
|
||||
|
||||
@@ -917,6 +925,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
link_preview_options: ODVInput["LinkPreviewOptions"] = DEFAULT_NONE,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
*,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
@@ -965,6 +974,9 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
business_connection_id (:obj:`str`, optional): |business_id_str|
|
||||
|
||||
.. versionadded:: 21.1
|
||||
message_effect_id (:obj:`str`, optional): |message_effect_id|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
|
||||
Keyword Args:
|
||||
allow_sending_without_reply (:obj:`bool`, optional): |allow_sending_without_reply|
|
||||
@@ -1022,6 +1034,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
parse_mode=parse_mode,
|
||||
link_preview_options=link_preview_options,
|
||||
reply_parameters=reply_parameters,
|
||||
message_effect_id=message_effect_id,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
@@ -1150,7 +1163,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
Note:
|
||||
Since the release of Bot API 5.5 it can be impossible to forward messages from
|
||||
some chats. Use the attributes :attr:`telegram.Message.has_protected_content` and
|
||||
:attr:`telegram.Chat.has_protected_content` to check this.
|
||||
:attr:`telegram.ChatFullInfo.has_protected_content` to check this.
|
||||
|
||||
As a workaround, it is still possible to use :meth:`copy_message`. However, this
|
||||
behaviour is undocumented and might be changed by Telegram.
|
||||
@@ -1270,6 +1283,8 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
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,
|
||||
*,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
@@ -1333,6 +1348,12 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
business_connection_id (:obj:`str`, optional): |business_id_str|
|
||||
|
||||
.. versionadded:: 21.1
|
||||
message_effect_id (:obj:`str`, optional): |message_effect_id|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
show_caption_above_media (:obj:`bool`, optional): Pass |show_cap_above_med|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
|
||||
Keyword Args:
|
||||
allow_sending_without_reply (:obj:`bool`, optional): |allow_sending_without_reply|
|
||||
@@ -1370,6 +1391,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
"chat_id": chat_id,
|
||||
"photo": self._parse_file_input(photo, PhotoSize, filename=filename),
|
||||
"has_spoiler": has_spoiler,
|
||||
"show_caption_above_media": show_caption_above_media,
|
||||
}
|
||||
|
||||
return await self._send_message(
|
||||
@@ -1391,6 +1413,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def send_audio(
|
||||
@@ -1410,6 +1433,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
thumbnail: Optional[FileInput] = None,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
*,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
@@ -1482,6 +1506,9 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
business_connection_id (:obj:`str`, optional): |business_id_str|
|
||||
|
||||
.. versionadded:: 21.1
|
||||
message_effect_id (:obj:`str`, optional): |message_effect_id|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
|
||||
Keyword Args:
|
||||
allow_sending_without_reply (:obj:`bool`, optional): |allow_sending_without_reply|
|
||||
@@ -1543,6 +1570,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def send_document(
|
||||
@@ -1560,6 +1588,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
thumbnail: Optional[FileInput] = None,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
*,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
@@ -1631,6 +1660,9 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
business_connection_id (:obj:`str`, optional): |business_id_str|
|
||||
|
||||
.. versionadded:: 21.1
|
||||
message_effect_id (:obj:`str`, optional): |message_effect_id|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
|
||||
Keyword Args:
|
||||
allow_sending_without_reply (:obj:`bool`, optional): |allow_sending_without_reply|
|
||||
@@ -1688,6 +1720,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def send_sticker(
|
||||
@@ -1701,6 +1734,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
emoji: Optional[str] = None,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
*,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
@@ -1752,6 +1786,9 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
business_connection_id (:obj:`str`, optional): |business_id_str|
|
||||
|
||||
.. versionadded:: 21.1
|
||||
message_effect_id (:obj:`str`, optional): |message_effect_id|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
|
||||
Keyword Args:
|
||||
allow_sending_without_reply (:obj:`bool`, optional): |allow_sending_without_reply|
|
||||
@@ -1801,6 +1838,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def send_video(
|
||||
@@ -1822,6 +1860,8 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
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,
|
||||
*,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
@@ -1902,6 +1942,12 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
business_connection_id (:obj:`str`, optional): |business_id_str|
|
||||
|
||||
.. versionadded:: 21.1
|
||||
message_effect_id (:obj:`str`, optional): |message_effect_id|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
show_caption_above_media (:obj:`bool`, optional): Pass |show_cap_above_med|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
|
||||
Keyword Args:
|
||||
allow_sending_without_reply (:obj:`bool`, optional): |allow_sending_without_reply|
|
||||
@@ -1944,6 +1990,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
"supports_streaming": supports_streaming,
|
||||
"thumbnail": self._parse_file_input(thumbnail, attach=True) if thumbnail else None,
|
||||
"has_spoiler": has_spoiler,
|
||||
"show_caption_above_media": show_caption_above_media,
|
||||
}
|
||||
|
||||
return await self._send_message(
|
||||
@@ -1965,6 +2012,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def send_video_note(
|
||||
@@ -1980,6 +2028,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
thumbnail: Optional[FileInput] = None,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
*,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
@@ -2045,6 +2094,9 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
business_connection_id (:obj:`str`, optional): |business_id_str|
|
||||
|
||||
.. versionadded:: 21.1
|
||||
message_effect_id (:obj:`str`, optional): |message_effect_id|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
|
||||
Keyword Args:
|
||||
allow_sending_without_reply (:obj:`bool`, optional): |allow_sending_without_reply|
|
||||
@@ -2102,6 +2154,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def send_animation(
|
||||
@@ -2122,6 +2175,8 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
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,
|
||||
*,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
@@ -2196,6 +2251,12 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
business_connection_id (:obj:`str`, optional): |business_id_str|
|
||||
|
||||
.. versionadded:: 21.1
|
||||
message_effect_id (:obj:`str`, optional): |message_effect_id|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
show_caption_above_media (:obj:`bool`, optional): Pass |show_cap_above_med|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
|
||||
Keyword Args:
|
||||
allow_sending_without_reply (:obj:`bool`, optional): |allow_sending_without_reply|
|
||||
@@ -2237,6 +2298,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
"height": height,
|
||||
"thumbnail": self._parse_file_input(thumbnail, attach=True) if thumbnail else None,
|
||||
"has_spoiler": has_spoiler,
|
||||
"show_caption_above_media": show_caption_above_media,
|
||||
}
|
||||
|
||||
return await self._send_message(
|
||||
@@ -2258,6 +2320,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def send_voice(
|
||||
@@ -2274,6 +2337,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
message_thread_id: Optional[int] = None,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
*,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
@@ -2287,9 +2351,10 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
"""
|
||||
Use this method to send audio files, if you want Telegram clients to display the file
|
||||
as a playable voice message. For this to work, your audio must be in an ``.ogg`` file
|
||||
encoded with OPUS (other formats may be sent as Audio or Document). Bots can currently
|
||||
send voice messages of up to :tg-const:`telegram.constants.FileSizeLimit.FILESIZE_UPLOAD`
|
||||
in size, this limit may be changed in the future.
|
||||
encoded with OPUS , or in .MP3 format, or in .M4A format (other formats may be sent as
|
||||
:class:`~telegram.Audio` or :class:`~telegram.Document`). Bots can currently send voice
|
||||
messages of up to :tg-const:`telegram.constants.FileSizeLimit.FILESIZE_UPLOAD` in size,
|
||||
this limit may be changed in the future.
|
||||
|
||||
Note:
|
||||
To use this method, the file must have the type :mimetype:`audio/ogg` and be no more
|
||||
@@ -2341,6 +2406,9 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
business_connection_id (:obj:`str`, optional): |business_id_str|
|
||||
|
||||
.. versionadded:: 21.1
|
||||
message_effect_id (:obj:`str`, optional): |message_effect_id|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
|
||||
Keyword Args:
|
||||
allow_sending_without_reply (:obj:`bool`, optional): |allow_sending_without_reply|
|
||||
@@ -2399,6 +2467,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def send_media_group(
|
||||
@@ -2412,6 +2481,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
message_thread_id: Optional[int] = None,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
*,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
@@ -2462,6 +2532,9 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
business_connection_id (:obj:`str`, optional): |business_id_str|
|
||||
|
||||
.. versionadded:: 21.1
|
||||
message_effect_id (:obj:`str`, optional): |message_effect_id|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
|
||||
Keyword Args:
|
||||
allow_sending_without_reply (:obj:`bool`, optional): |allow_sending_without_reply|
|
||||
@@ -2555,6 +2628,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
"message_thread_id": message_thread_id,
|
||||
"reply_parameters": reply_parameters,
|
||||
"business_connection_id": business_connection_id,
|
||||
"message_effect_id": message_effect_id,
|
||||
}
|
||||
|
||||
result = await self._post(
|
||||
@@ -2584,6 +2658,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
message_thread_id: Optional[int] = None,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
*,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
@@ -2610,7 +2685,9 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
live_period (:obj:`int`, optional): Period in seconds for which the location will be
|
||||
updated, should be between
|
||||
:tg-const:`telegram.constants.LocationLimit.MIN_LIVE_PERIOD` and
|
||||
:tg-const:`telegram.constants.LocationLimit.MAX_LIVE_PERIOD`.
|
||||
:tg-const:`telegram.constants.LocationLimit.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.constants.LocationLimit.MIN_HEADING` and
|
||||
@@ -2638,6 +2715,9 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
business_connection_id (:obj:`str`, optional): |business_id_str|
|
||||
|
||||
.. versionadded:: 21.1
|
||||
message_effect_id (:obj:`str`, optional): |message_effect_id|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
|
||||
Keyword Args:
|
||||
allow_sending_without_reply (:obj:`bool`, optional): |allow_sending_without_reply|
|
||||
@@ -2707,6 +2787,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def edit_message_live_location(
|
||||
@@ -2720,6 +2801,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
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,
|
||||
@@ -2758,6 +2840,15 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
if specified.
|
||||
reply_markup (:class:`telegram.InlineKeyboardMarkup`, optional): An object for a new
|
||||
inline keyboard.
|
||||
live_period (:obj:`int`, optional): New period in seconds during which the location
|
||||
can be updated, starting from the message send date. If
|
||||
:tg-const:`telegram.constants.LocationLimit.LIVE_PERIOD_FOREVER` is specified,
|
||||
then the location can be updated forever. Otherwise, the new value must not exceed
|
||||
the current ``live_period`` by more than a day, and the live location expiration
|
||||
date must remain within the next 90 days. If not specified, then ``live_period``
|
||||
remains unchanged
|
||||
|
||||
.. versionadded:: 21.2.
|
||||
|
||||
Keyword Args:
|
||||
location (:class:`telegram.Location`, optional): The location to send.
|
||||
@@ -2790,6 +2881,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
"horizontal_accuracy": horizontal_accuracy,
|
||||
"heading": heading,
|
||||
"proximity_alert_radius": proximity_alert_radius,
|
||||
"live_period": live_period,
|
||||
}
|
||||
|
||||
return await self._send_message(
|
||||
@@ -2867,6 +2959,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
message_thread_id: Optional[int] = None,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
*,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
@@ -2919,6 +3012,9 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
business_connection_id (:obj:`str`, optional): |business_id_str|
|
||||
|
||||
.. versionadded:: 21.1
|
||||
message_effect_id (:obj:`str`, optional): |message_effect_id|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
|
||||
Keyword Args:
|
||||
allow_sending_without_reply (:obj:`bool`, optional): |allow_sending_without_reply|
|
||||
@@ -2999,6 +3095,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def send_contact(
|
||||
@@ -3014,6 +3111,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
message_thread_id: Optional[int] = None,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
*,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
@@ -3056,6 +3154,9 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
business_connection_id (:obj:`str`, optional): |business_id_str|
|
||||
|
||||
.. versionadded:: 21.1
|
||||
message_effect_id (:obj:`str`, optional): |message_effect_id|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
|
||||
Keyword Args:
|
||||
allow_sending_without_reply (:obj:`bool`, optional): |allow_sending_without_reply|
|
||||
@@ -3127,6 +3228,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def send_game(
|
||||
@@ -3139,6 +3241,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
message_thread_id: Optional[int] = None,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
*,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
@@ -3171,6 +3274,9 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
business_connection_id (:obj:`str`, optional): |business_id_str|
|
||||
|
||||
.. versionadded:: 21.1
|
||||
message_effect_id (:obj:`str`, optional): |message_effect_id|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
|
||||
Keyword Args:
|
||||
allow_sending_without_reply (:obj:`bool`, optional): |allow_sending_without_reply|
|
||||
@@ -3217,6 +3323,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def send_chat_action(
|
||||
@@ -3938,6 +4045,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
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,
|
||||
@@ -3969,6 +4077,9 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
|sequenceargs|
|
||||
reply_markup (:class:`telegram.InlineKeyboardMarkup`, optional): An object for an
|
||||
inline keyboard.
|
||||
show_caption_above_media (:obj:`bool`, optional): Pass |show_cap_above_med|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, if edited message is not an inline message, the
|
||||
@@ -3982,6 +4093,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
"chat_id": chat_id,
|
||||
"message_id": message_id,
|
||||
"inline_message_id": inline_message_id,
|
||||
"show_caption_above_media": show_caption_above_media,
|
||||
}
|
||||
|
||||
return await self._send_message(
|
||||
@@ -4195,10 +4307,12 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
except NotImplementedError:
|
||||
arg_read_timeout = 2
|
||||
self._warn(
|
||||
f"The class {self._request[0].__class__.__name__} does not override "
|
||||
"the property `read_timeout`. Overriding this property will be mandatory in "
|
||||
"future versions. Using 2 seconds as fallback.",
|
||||
PTBDeprecationWarning,
|
||||
PTBDeprecationWarning(
|
||||
"20.7",
|
||||
f"The class {self._request[0].__class__.__name__} does not override "
|
||||
"the property `read_timeout`. Overriding this property will be mandatory "
|
||||
"in future versions. Using 2 seconds as fallback.",
|
||||
),
|
||||
stacklevel=2,
|
||||
)
|
||||
|
||||
@@ -4434,16 +4548,19 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
pool_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
) -> Chat:
|
||||
) -> ChatFullInfo:
|
||||
"""
|
||||
Use this method to get up to date information about the chat (current name of the user for
|
||||
one-on-one conversations, current username of a user, group or channel, etc.).
|
||||
|
||||
.. versionchanged:: 21.2
|
||||
In accordance to Bot API 7.3, this method now returns a :class:`telegram.ChatFullInfo`.
|
||||
|
||||
Args:
|
||||
chat_id (:obj:`int` | :obj:`str`): |chat_id_channel|
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Chat`
|
||||
:class:`telegram.ChatFullInfo`
|
||||
|
||||
Raises:
|
||||
:class:`telegram.error.TelegramError`
|
||||
@@ -4461,7 +4578,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
return Chat.de_json(result, self) # type: ignore[return-value]
|
||||
return ChatFullInfo.de_json(result, self) # type: ignore[return-value]
|
||||
|
||||
async def get_chat_administrators(
|
||||
self,
|
||||
@@ -4589,8 +4706,8 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
) -> bool:
|
||||
"""Use this method to set a new group sticker set for a supergroup.
|
||||
The bot must be an administrator in the chat for this to work and must have the appropriate
|
||||
admin rights. Use the field :attr:`telegram.Chat.can_set_sticker_set` optionally returned
|
||||
in :meth:`get_chat` requests to check if the bot can use this method.
|
||||
admin rights. Use the field :attr:`telegram.ChatFullInfo.can_set_sticker_set` optionally
|
||||
returned in :meth:`get_chat` requests to check if the bot can use this method.
|
||||
|
||||
Args:
|
||||
chat_id (:obj:`int` | :obj:`str`): |chat_id_group|
|
||||
@@ -4623,7 +4740,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
) -> bool:
|
||||
"""Use this method to delete a group sticker set from a supergroup. The bot must be an
|
||||
administrator in the chat for this to work and must have the appropriate admin rights.
|
||||
Use the field :attr:`telegram.Chat.can_set_sticker_set` optionally returned in
|
||||
Use the field :attr:`telegram.ChatFullInfo.can_set_sticker_set` optionally returned in
|
||||
:meth:`get_chat` requests to check if the bot can use this method.
|
||||
|
||||
Args:
|
||||
@@ -4801,7 +4918,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
title: str,
|
||||
description: str,
|
||||
payload: str,
|
||||
provider_token: str,
|
||||
provider_token: Optional[str], # This arg is now optional as of Bot API 7.4
|
||||
currency: str,
|
||||
prices: Sequence["LabeledPrice"],
|
||||
start_parameter: Optional[str] = None,
|
||||
@@ -4824,6 +4941,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
message_thread_id: Optional[int] = None,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
*,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
@@ -4855,12 +4973,19 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
: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`): Payments 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>`_.
|
||||
<https://core.telegram.org/bots/payments#supported-currencies>`_. Pass ``XTR`` for
|
||||
payment in |tg_stars|.
|
||||
prices (Sequence[:class:`telegram.LabeledPrice`]): Price breakdown, a sequence
|
||||
of components (e.g. product price, tax, discount, delivery cost, delivery tax,
|
||||
bonus, etc.).
|
||||
bonus, etc.). Must contain exactly one item for payment in |tg_stars|.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceargs|
|
||||
@@ -4869,7 +4994,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
a 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``.
|
||||
majority of currencies). Defaults to ``0``. Not supported for payment in |tg_stars|
|
||||
|
||||
.. versionadded:: 13.5
|
||||
suggested_tip_amounts (Sequence[:obj:`int`], optional): An array of
|
||||
@@ -4902,19 +5027,20 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
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.
|
||||
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
|
||||
to complete the order.
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
the shipping method. Ignored for payments in |tg_stars|.
|
||||
disable_notification (:obj:`bool`, optional): |disable_notification|
|
||||
protect_content (:obj:`bool`, optional): |protect_content|
|
||||
|
||||
@@ -4929,6 +5055,9 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
reply_parameters (:class:`telegram.ReplyParameters`, optional): |reply_parameters|
|
||||
|
||||
.. versionadded:: 20.8
|
||||
message_effect_id (:obj:`str`, optional): |message_effect_id|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
|
||||
Keyword Args:
|
||||
allow_sending_without_reply (:obj:`bool`, optional): |allow_sending_without_reply|
|
||||
@@ -4997,6 +5126,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def answer_shipping_query(
|
||||
@@ -5311,7 +5441,8 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
|
||||
.. versionadded:: 20.6
|
||||
can_edit_stories (:obj:`bool`, optional): Pass :obj:`True`, if the administrator can
|
||||
edit stories posted by other users.
|
||||
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
|
||||
can_delete_stories (:obj:`bool`, optional): Pass :obj:`True`, if the administrator can
|
||||
@@ -6312,7 +6443,6 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
name: str,
|
||||
title: str,
|
||||
stickers: Sequence["InputSticker"],
|
||||
sticker_format: Optional[str] = None,
|
||||
sticker_type: Optional[str] = None,
|
||||
needs_repainting: Optional[bool] = None,
|
||||
*,
|
||||
@@ -6339,6 +6469,9 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
Removed the deprecated parameters mentioned above and adjusted the order of the
|
||||
parameters.
|
||||
|
||||
.. versionremoved:: 21.2
|
||||
Removed the deprecated parameter ``sticker_format``.
|
||||
|
||||
Args:
|
||||
user_id (:obj:`int`): User identifier of created sticker set owner.
|
||||
name (:obj:`str`): Short name of sticker set, to be used in t.me/addstickers/ URLs
|
||||
@@ -6358,16 +6491,6 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
|
||||
.. versionadded:: 20.2
|
||||
|
||||
sticker_format (:obj:`str`): Format of stickers in the set, must be one of
|
||||
:attr:`~telegram.constants.StickerFormat.STATIC`,
|
||||
:attr:`~telegram.constants.StickerFormat.ANIMATED` or
|
||||
:attr:`~telegram.constants.StickerFormat.VIDEO`.
|
||||
|
||||
.. versionadded:: 20.2
|
||||
|
||||
.. deprecated:: 21.1
|
||||
Use :paramref:`telegram.InputSticker.format` instead.
|
||||
|
||||
sticker_type (:obj:`str`, optional): Type of stickers in the set, pass
|
||||
:attr:`telegram.Sticker.REGULAR` or :attr:`telegram.Sticker.MASK`, or
|
||||
:attr:`telegram.Sticker.CUSTOM_EMOJI`. By default, a regular sticker set is created
|
||||
@@ -6387,20 +6510,11 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
Raises:
|
||||
:class:`telegram.error.TelegramError`
|
||||
"""
|
||||
if sticker_format is not None:
|
||||
warn(
|
||||
"The parameter `sticker_format` is deprecated. Use the parameter"
|
||||
" `InputSticker.format` in the parameter `stickers` instead.",
|
||||
stacklevel=2,
|
||||
category=PTBDeprecationWarning,
|
||||
)
|
||||
|
||||
data: JSONDict = {
|
||||
"user_id": user_id,
|
||||
"name": name,
|
||||
"title": title,
|
||||
"stickers": stickers,
|
||||
"sticker_format": sticker_format,
|
||||
"sticker_type": sticker_type,
|
||||
"needs_repainting": needs_repainting,
|
||||
}
|
||||
@@ -6815,7 +6929,7 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
self,
|
||||
chat_id: Union[int, str],
|
||||
question: str,
|
||||
options: Sequence[str],
|
||||
options: Sequence[Union[str, "InputPollOption"]],
|
||||
is_anonymous: Optional[bool] = None,
|
||||
type: Optional[str] = None, # pylint: disable=redefined-builtin
|
||||
allows_multiple_answers: Optional[bool] = None,
|
||||
@@ -6832,6 +6946,9 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
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,
|
||||
*,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
@@ -6848,14 +6965,20 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
chat_id (:obj:`int` | :obj:`str`): |chat_id_channel|
|
||||
question (:obj:`str`): Poll question, :tg-const:`telegram.Poll.MIN_QUESTION_LENGTH`-
|
||||
:tg-const:`telegram.Poll.MAX_QUESTION_LENGTH` characters.
|
||||
options (Sequence[:obj:`str`]): Sequence of answer options,
|
||||
options (Sequence[:obj:`str` | :class:`telegram.InputPollOption`]): Sequence of
|
||||
:tg-const:`telegram.Poll.MIN_OPTION_NUMBER`-
|
||||
:tg-const:`telegram.Poll.MAX_OPTION_NUMBER` strings
|
||||
:tg-const:`telegram.Poll.MAX_OPTION_NUMBER` answer options. Each option may either
|
||||
be a string with
|
||||
:tg-const:`telegram.Poll.MIN_OPTION_LENGTH`-
|
||||
:tg-const:`telegram.Poll.MAX_OPTION_LENGTH` characters each.
|
||||
:tg-const:`telegram.Poll.MAX_OPTION_LENGTH` characters or an
|
||||
:class:`~telegram.InputPollOption` object. Strings are converted to
|
||||
:class:`~telegram.InputPollOption` objects automatically.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceargs|
|
||||
|
||||
.. versionchanged:: 21.2
|
||||
Bot API 7.3 adds support for :class:`~telegram.InputPollOption` objects.
|
||||
is_anonymous (:obj:`bool`, optional): :obj:`True`, if the poll needs to be anonymous,
|
||||
defaults to :obj:`True`.
|
||||
type (:obj:`str`, optional): Poll type, :tg-const:`telegram.Poll.QUIZ` or
|
||||
@@ -6910,6 +7033,19 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
business_connection_id (:obj:`str`, optional): |business_id_str|
|
||||
|
||||
.. versionadded:: 21.1
|
||||
question_parse_mode (:obj:`str`, optional): Mode for parsing entities in the question.
|
||||
See the constants in :class:`telegram.constants.ParseMode` for the available modes.
|
||||
Currently, only custom emoji entities are allowed.
|
||||
|
||||
.. versionadded:: 21.2
|
||||
question_entities (Sequence[:class:`telegram.Message`], optional): Special entities
|
||||
that appear in the poll :paramref:`question`. It can be specified instead of
|
||||
:paramref:`question_parse_mode`.
|
||||
|
||||
.. versionadded:: 21.2
|
||||
message_effect_id (:obj:`str`, optional): |message_effect_id|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
|
||||
Keyword Args:
|
||||
allow_sending_without_reply (:obj:`bool`, optional): |allow_sending_without_reply|
|
||||
@@ -6941,7 +7077,10 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
data: JSONDict = {
|
||||
"chat_id": chat_id,
|
||||
"question": question,
|
||||
"options": options,
|
||||
"options": [
|
||||
InputPollOption(option) if isinstance(option, str) else option
|
||||
for option in options
|
||||
],
|
||||
"explanation_parse_mode": explanation_parse_mode,
|
||||
"is_anonymous": is_anonymous,
|
||||
"type": type,
|
||||
@@ -6952,6 +7091,8 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
"explanation_entities": explanation_entities,
|
||||
"open_period": open_period,
|
||||
"close_date": close_date,
|
||||
"question_parse_mode": question_parse_mode,
|
||||
"question_entities": question_entities,
|
||||
}
|
||||
|
||||
return await self._send_message(
|
||||
@@ -6970,6 +7111,7 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def stop_poll(
|
||||
@@ -7027,6 +7169,7 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
message_thread_id: Optional[int] = None,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
*,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
@@ -7073,6 +7216,9 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
business_connection_id (:obj:`str`, optional): |business_id_str|
|
||||
|
||||
.. versionadded:: 21.1
|
||||
message_effect_id (:obj:`str`, optional): |message_effect_id|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
|
||||
Keyword Args:
|
||||
allow_sending_without_reply (:obj:`bool`, optional): |allow_sending_without_reply|
|
||||
@@ -7120,6 +7266,7 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def get_my_default_administrator_rights(
|
||||
@@ -7389,7 +7536,7 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
minutes.
|
||||
|
||||
Returns:
|
||||
:obj:`True`: On success
|
||||
:obj:`True`: On success, :obj:`True` is returned.
|
||||
|
||||
Raises:
|
||||
:class:`telegram.error.TelegramError`
|
||||
@@ -7420,7 +7567,7 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
10 minutes after the bot is launched.
|
||||
|
||||
Returns:
|
||||
:obj:`True`: On success
|
||||
:obj:`True`: On success, :obj:`True` is returned.
|
||||
|
||||
Raises:
|
||||
:class:`telegram.error.TelegramError`
|
||||
@@ -7448,6 +7595,7 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
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,
|
||||
@@ -7491,6 +7639,9 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
reply_parameters (:class:`telegram.ReplyParameters`, optional): |reply_parameters|
|
||||
|
||||
.. versionadded:: 20.8
|
||||
show_caption_above_media (:obj:`bool`, optional): Pass |show_cap_above_med|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
|
||||
Keyword Args:
|
||||
allow_sending_without_reply (:obj:`bool`, optional): |allow_sending_without_reply|
|
||||
@@ -7513,7 +7664,8 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
|keyword_only_arg|
|
||||
|
||||
Returns:
|
||||
:class:`telegram.MessageId`: On success
|
||||
:class:`telegram.MessageId`: On success, the :class:`telegram.MessageId` of the sent
|
||||
message is returned.
|
||||
|
||||
Raises:
|
||||
:class:`telegram.error.TelegramError`
|
||||
@@ -7547,6 +7699,7 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
"reply_markup": reply_markup,
|
||||
"message_thread_id": message_thread_id,
|
||||
"reply_parameters": reply_parameters,
|
||||
"show_caption_above_media": show_caption_above_media,
|
||||
}
|
||||
|
||||
result = await self._post(
|
||||
@@ -7715,7 +7868,7 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
title: str,
|
||||
description: str,
|
||||
payload: str,
|
||||
provider_token: str,
|
||||
provider_token: Optional[str], # This arg is now optional as of Bot API 7.4
|
||||
currency: str,
|
||||
prices: Sequence["LabeledPrice"],
|
||||
max_tip_amount: Optional[int] = None,
|
||||
@@ -7754,12 +7907,19 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
: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`): Payments 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>`_.
|
||||
<https://core.telegram.org/bots/payments#supported-currencies>`_. Pass ``XTR`` for
|
||||
payments in |tg_stars|.
|
||||
prices (Sequence[:class:`telegram.LabeledPrice`)]: Price breakdown, a sequence
|
||||
of components (e.g. product price, tax, discount, delivery cost, delivery tax,
|
||||
bonus, etc.).
|
||||
bonus, etc.). Must contain exactly one item for payments in |tg_stars|.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceargs|
|
||||
@@ -7768,7 +7928,8 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
a 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``.
|
||||
majority of currencies). Defaults to ``0``. Not supported for payments in
|
||||
|tg_stars|.
|
||||
suggested_tip_amounts (Sequence[:obj:`int`], optional): An array of
|
||||
suggested amounts of tips in the *smallest* units of the currency (integer, **not**
|
||||
float/double). At most :tg-const:`telegram.Invoice.MAX_TIP_AMOUNTS` suggested tip
|
||||
@@ -7787,19 +7948,20 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
the shipping method. Ignored for payments in |tg_stars|.
|
||||
|
||||
Returns:
|
||||
:class:`str`: On success, the created invoice link is returned.
|
||||
@@ -8867,7 +9029,48 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
def to_dict(self, recursive: bool = True) -> JSONDict:
|
||||
async def refund_star_payment(
|
||||
self,
|
||||
user_id: int,
|
||||
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:
|
||||
"""Refunds a successful payment in |tg_stars|.
|
||||
|
||||
.. versionadded:: 21.3
|
||||
|
||||
Args:
|
||||
user_id (:obj:`int`): User identifier of the user whose payment will be refunded.
|
||||
telegram_payment_charge_id (:obj:`str`): Telegram payment identifier.
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
|
||||
Raises:
|
||||
:class:`telegram.error.TelegramError`
|
||||
|
||||
"""
|
||||
data: JSONDict = {
|
||||
"user_id": user_id,
|
||||
"telegram_payment_charge_id": telegram_payment_charge_id,
|
||||
}
|
||||
|
||||
return await self._post(
|
||||
"refundStarPayment",
|
||||
data,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
def to_dict(self, recursive: bool = True) -> JSONDict: # noqa: ARG002
|
||||
"""See :meth:`telegram.TelegramObject.to_dict`."""
|
||||
data: JSONDict = {"id": self.id, "username": self.username, "first_name": self.first_name}
|
||||
|
||||
@@ -9117,3 +9320,5 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
"""Alias for :meth:`get_business_connection`"""
|
||||
replaceStickerInSet = replace_sticker_in_set
|
||||
"""Alias for :meth:`replace_sticker_in_set`"""
|
||||
refundStarPayment = refund_star_payment
|
||||
"""Alias for :meth:`refund_star_payment`"""
|
||||
|
||||
@@ -189,7 +189,7 @@ class BusinessMessagesDeleted(TelegramObject):
|
||||
|
||||
class BusinessIntro(TelegramObject):
|
||||
"""
|
||||
This object represents the intro of a business account.
|
||||
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
|
||||
@@ -246,7 +246,7 @@ class BusinessIntro(TelegramObject):
|
||||
|
||||
class BusinessLocation(TelegramObject):
|
||||
"""
|
||||
This object represents the location of a business account.
|
||||
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
|
||||
@@ -298,7 +298,7 @@ class BusinessLocation(TelegramObject):
|
||||
|
||||
class BusinessOpeningHoursInterval(TelegramObject):
|
||||
"""
|
||||
This object represents the time intervals describing business opening hours.
|
||||
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
|
||||
@@ -390,7 +390,7 @@ class BusinessOpeningHoursInterval(TelegramObject):
|
||||
|
||||
class BusinessOpeningHours(TelegramObject):
|
||||
"""
|
||||
This object represents the opening hours of a business account.
|
||||
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
|
||||
|
||||
@@ -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] = (
|
||||
|
||||
+161
-573
File diff suppressed because it is too large
Load Diff
@@ -80,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
|
||||
@@ -128,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
|
||||
|
||||
@@ -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)
|
||||
@@ -235,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
|
||||
@@ -294,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
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -27,8 +27,6 @@ from telegram._telegramobject import TelegramObject
|
||||
from telegram._utils import enum
|
||||
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||
from telegram._utils.types import JSONDict
|
||||
from telegram._utils.warnings import warn
|
||||
from telegram.warnings import PTBDeprecationWarning
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import Bot
|
||||
@@ -237,20 +235,12 @@ class StickerSet(TelegramObject):
|
||||
.. 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.
|
||||
|
||||
.. deprecated:: 21.1
|
||||
Bot API 7.2 deprecated this field. This parameter will be removed in a future
|
||||
version of the library.
|
||||
is_video (:obj:`bool`): :obj:`True`, if the sticker set contains video stickers.
|
||||
.. versionadded:: 13.11
|
||||
|
||||
.. deprecated:: 21.1
|
||||
Bot API 7.2 deprecated this field. This parameter will be removed in a future
|
||||
version of the library.
|
||||
stickers (Sequence[:class:`telegram.Sticker`]): List of all set stickers.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
@@ -269,17 +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.
|
||||
|
||||
.. deprecated:: 21.1
|
||||
Bot API 7.2 deprecated this field. This parameter will be removed in a future
|
||||
version of the library.
|
||||
is_video (:obj:`bool`): :obj:`True`, if the sticker set contains video stickers.
|
||||
.. versionadded:: 13.11
|
||||
|
||||
.. deprecated:: 21.1
|
||||
Bot API 7.2 deprecated this field. This parameter will be removed in a future
|
||||
version of the library.
|
||||
stickers (Tuple[:class:`telegram.Sticker`]): List of all set stickers.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
@@ -297,8 +276,6 @@ class StickerSet(TelegramObject):
|
||||
"""
|
||||
|
||||
__slots__ = (
|
||||
"is_animated",
|
||||
"is_video",
|
||||
"name",
|
||||
"sticker_type",
|
||||
"stickers",
|
||||
@@ -312,8 +289,6 @@ class StickerSet(TelegramObject):
|
||||
title: str,
|
||||
stickers: Sequence[Sticker],
|
||||
sticker_type: str,
|
||||
is_animated: Optional[bool] = None,
|
||||
is_video: Optional[bool] = None,
|
||||
thumbnail: Optional[PhotoSize] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
@@ -325,15 +300,6 @@ class StickerSet(TelegramObject):
|
||||
self.sticker_type: str = sticker_type
|
||||
# Optional
|
||||
self.thumbnail: Optional[PhotoSize] = thumbnail
|
||||
if is_animated is not None or is_video is not None:
|
||||
warn(
|
||||
"The parameters `is_animated` and `is_video` are deprecated and will be removed "
|
||||
"in a future version.",
|
||||
PTBDeprecationWarning,
|
||||
stacklevel=2,
|
||||
)
|
||||
self.is_animated: Optional[bool] = is_animated
|
||||
self.is_video: Optional[bool] = is_video
|
||||
self._id_attrs = (self.name,)
|
||||
|
||||
self._freeze()
|
||||
@@ -350,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
|
||||
|
||||
+163
-64
@@ -25,6 +25,7 @@ from html import escape
|
||||
from typing import TYPE_CHECKING, Dict, List, Optional, Sequence, Tuple, TypedDict, Union
|
||||
|
||||
from telegram._chat import Chat
|
||||
from telegram._chatbackground import ChatBackground
|
||||
from telegram._chatboost import ChatBoostAdded
|
||||
from telegram._dice import Dice
|
||||
from telegram._files.animation import Animation
|
||||
@@ -64,6 +65,7 @@ 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.defaultvalue import DEFAULT_NONE, DefaultValue
|
||||
from telegram._utils.entities import parse_message_entities, parse_message_entity
|
||||
from telegram._utils.types import (
|
||||
CorrectOptionID,
|
||||
FileInput,
|
||||
@@ -99,6 +101,7 @@ if TYPE_CHECKING:
|
||||
InputMediaDocument,
|
||||
InputMediaPhoto,
|
||||
InputMediaVideo,
|
||||
InputPollOption,
|
||||
LabeledPrice,
|
||||
MessageId,
|
||||
MessageOrigin,
|
||||
@@ -198,7 +201,7 @@ class MaybeInaccessibleMessage(TelegramObject):
|
||||
data["date"] = from_timestamp(data["date"], tzinfo=loc_tzinfo)
|
||||
|
||||
data["chat"] = Chat.de_json(data.get("chat"), bot)
|
||||
return super()._de_json(data=data, bot=bot)
|
||||
return super()._de_json(data=data, bot=bot, api_kwargs=api_kwargs)
|
||||
|
||||
|
||||
class InaccessibleMessage(MaybeInaccessibleMessage):
|
||||
@@ -252,8 +255,8 @@ class Message(MaybeInaccessibleMessage):
|
||||
|
||||
.. versionchanged:: 20.8
|
||||
* This class is now a subclass of :class:`telegram.MaybeInaccessibleMessage`.
|
||||
* The :paramref:`pinned_message` now can be either class:`telegram.Message` or
|
||||
class:`telegram.InaccessibleMessage`.
|
||||
* The :paramref:`pinned_message` now can be either :class:`telegram.Message` or
|
||||
:class:`telegram.InaccessibleMessage`.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
@@ -325,6 +328,11 @@ class Message(MaybeInaccessibleMessage):
|
||||
|
||||
.. versionadded:: 20.8
|
||||
|
||||
effect_id (:obj:`str`, optional): Unique identifier of the message effect added to the
|
||||
message.
|
||||
|
||||
..versionadded:: 21.3
|
||||
|
||||
caption_entities (Sequence[:class:`telegram.MessageEntity`], optional): For messages with a
|
||||
Caption. Special entities like usernames, URLs, bot commands, etc. that appear in the
|
||||
caption. See :attr:`Message.parse_caption_entity` and :attr:`parse_caption_entities`
|
||||
@@ -334,6 +342,9 @@ class Message(MaybeInaccessibleMessage):
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceclassargs|
|
||||
|
||||
show_caption_above_media (:obj:`bool`, optional): |show_cap_above_med|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
audio (:class:`telegram.Audio`, optional): Message is an audio file, information
|
||||
about the file.
|
||||
document (:class:`telegram.Document`, optional): Message is a general file, information
|
||||
@@ -408,8 +419,8 @@ class Message(MaybeInaccessibleMessage):
|
||||
:attr:`reply_to_message` fields even if it is itself a reply.
|
||||
|
||||
.. versionchanged:: 20.8
|
||||
This attribute now is either class:`telegram.Message` or
|
||||
class:`telegram.InaccessibleMessage`.
|
||||
This attribute now is either :class:`telegram.Message` or
|
||||
:class:`telegram.InaccessibleMessage`.
|
||||
invoice (:class:`telegram.Invoice`, optional): Message is an invoice for a payment,
|
||||
information about the invoice.
|
||||
successful_payment (:class:`telegram.SuccessfulPayment`, optional): Message is a service
|
||||
@@ -553,6 +564,11 @@ class Message(MaybeInaccessibleMessage):
|
||||
|
||||
.. versionadded:: 21.1
|
||||
|
||||
chat_background_set (:obj:`telegram.ChatBackground`, optional): Service message: chat
|
||||
background set.
|
||||
|
||||
.. versionadded:: 21.2
|
||||
|
||||
Attributes:
|
||||
message_id (:obj:`int`): Unique message identifier inside this chat.
|
||||
from_user (:class:`telegram.User`): Optional. Sender of the message; empty for messages
|
||||
@@ -609,6 +625,11 @@ class Message(MaybeInaccessibleMessage):
|
||||
|
||||
.. versionadded:: 20.8
|
||||
|
||||
effect_id (:obj:`str`): Optional. Unique identifier of the message effect added to the
|
||||
message.
|
||||
|
||||
..versionadded:: 21.3
|
||||
|
||||
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. For messages with a
|
||||
Caption. Special entities like usernames, URLs, bot commands, etc. that appear in the
|
||||
caption. See :attr:`Message.parse_caption_entity` and :attr:`parse_caption_entities`
|
||||
@@ -618,6 +639,9 @@ class Message(MaybeInaccessibleMessage):
|
||||
.. versionchanged:: 20.0
|
||||
|tupleclassattrs|
|
||||
|
||||
show_caption_above_media (:obj:`bool`): Optional. |show_cap_above_med|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
audio (:class:`telegram.Audio`): Optional. Message is an audio file, information
|
||||
about the file.
|
||||
|
||||
@@ -707,8 +731,8 @@ class Message(MaybeInaccessibleMessage):
|
||||
:attr:`reply_to_message` fields even if it is itself a reply.
|
||||
|
||||
.. versionchanged:: 20.8
|
||||
This attribute now is either class:`telegram.Message` or
|
||||
class:`telegram.InaccessibleMessage`.
|
||||
This attribute now is either :class:`telegram.Message` or
|
||||
:class:`telegram.InaccessibleMessage`.
|
||||
invoice (:class:`telegram.Invoice`): Optional. Message is an invoice for a payment,
|
||||
information about the invoice.
|
||||
successful_payment (:class:`telegram.SuccessfulPayment`): Optional. Message is a service
|
||||
@@ -853,6 +877,11 @@ class Message(MaybeInaccessibleMessage):
|
||||
|
||||
.. versionadded:: 21.1
|
||||
|
||||
chat_background_set (:obj:`telegram.ChatBackground`): Optional. Service message: chat
|
||||
background set
|
||||
|
||||
.. versionadded:: 21.2
|
||||
|
||||
.. |custom_emoji_no_md1_support| replace:: Since custom emoji entities are not supported by
|
||||
:attr:`~telegram.constants.ParseMode.MARKDOWN`, this method now raises a
|
||||
:exc:`ValueError` when encountering a custom emoji.
|
||||
@@ -876,6 +905,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
"caption",
|
||||
"caption_entities",
|
||||
"channel_chat_created",
|
||||
"chat_background_set",
|
||||
"chat_shared",
|
||||
"connected_website",
|
||||
"contact",
|
||||
@@ -883,6 +913,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
"dice",
|
||||
"document",
|
||||
"edit_date",
|
||||
"effect_id",
|
||||
"entities",
|
||||
"external_reply",
|
||||
"forum_topic_closed",
|
||||
@@ -928,6 +959,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
"sender_boost_count",
|
||||
"sender_business_bot",
|
||||
"sender_chat",
|
||||
"show_caption_above_media",
|
||||
"sticker",
|
||||
"story",
|
||||
"successful_payment",
|
||||
@@ -1029,6 +1061,9 @@ class Message(MaybeInaccessibleMessage):
|
||||
business_connection_id: Optional[str] = None,
|
||||
sender_business_bot: Optional[User] = None,
|
||||
is_from_offline: Optional[bool] = None,
|
||||
chat_background_set: Optional[ChatBackground] = None,
|
||||
effect_id: Optional[str] = None,
|
||||
show_caption_above_media: Optional[bool] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
@@ -1127,6 +1162,9 @@ class Message(MaybeInaccessibleMessage):
|
||||
self.business_connection_id: Optional[str] = business_connection_id
|
||||
self.sender_business_bot: Optional[User] = sender_business_bot
|
||||
self.is_from_offline: Optional[bool] = is_from_offline
|
||||
self.chat_background_set: Optional[ChatBackground] = chat_background_set
|
||||
self.effect_id: Optional[str] = effect_id
|
||||
self.show_caption_above_media: Optional[bool] = show_caption_above_media
|
||||
|
||||
self._effective_attachment = DEFAULT_NONE
|
||||
|
||||
@@ -1241,6 +1279,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
)
|
||||
data["users_shared"] = UsersShared.de_json(data.get("users_shared"), bot)
|
||||
data["chat_shared"] = ChatShared.de_json(data.get("chat_shared"), bot)
|
||||
data["chat_background_set"] = ChatBackground.de_json(data.get("chat_background_set"), bot)
|
||||
|
||||
# Unfortunately, this needs to be here due to cyclic imports
|
||||
from telegram._giveaway import ( # pylint: disable=import-outside-toplevel
|
||||
@@ -1462,7 +1501,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
quote_index: Optional[int] = None,
|
||||
target_chat_id: Optional[Union[int, str]] = None,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
message_thread_id: Optional[int] = None,
|
||||
message_thread_id: ODVInput[int] = DEFAULT_NONE,
|
||||
) -> _ReplyKwargs:
|
||||
"""
|
||||
Builds a dictionary with the keys ``chat_id`` and ``reply_parameters``. This dictionary can
|
||||
@@ -1562,9 +1601,11 @@ class Message(MaybeInaccessibleMessage):
|
||||
|
||||
if quote is not None:
|
||||
warn(
|
||||
"The `quote` parameter is deprecated in favor of the `do_quote` parameter. Please "
|
||||
"update your code to use `do_quote` instead.",
|
||||
PTBDeprecationWarning,
|
||||
PTBDeprecationWarning(
|
||||
"20.8",
|
||||
"The `quote` parameter is deprecated in favor of the `do_quote` parameter. "
|
||||
"Please update your code to use `do_quote` instead.",
|
||||
),
|
||||
stacklevel=2,
|
||||
)
|
||||
|
||||
@@ -1587,11 +1628,22 @@ class Message(MaybeInaccessibleMessage):
|
||||
def _parse_message_thread_id(
|
||||
self,
|
||||
chat_id: Union[str, int],
|
||||
message_thread_id: Optional[int] = None,
|
||||
message_thread_id: ODVInput[int] = DEFAULT_NONE,
|
||||
) -> Optional[int]:
|
||||
return message_thread_id or (
|
||||
self.message_thread_id if chat_id in {self.chat_id, self.chat.username} else None
|
||||
)
|
||||
# values set by user have the highest priority
|
||||
if not isinstance(message_thread_id, DefaultValue):
|
||||
return message_thread_id
|
||||
|
||||
# self.message_thread_id can be used for send_*.param.message_thread_id only if the
|
||||
# thread is a forum topic. It does not work if the thread is a chain of replies to a
|
||||
# message in a normal group. In that case, self.message_thread_id is just the message_id
|
||||
# of the first message in the chain.
|
||||
if not self.is_topic_message:
|
||||
return None
|
||||
|
||||
# Setting message_thread_id=self.message_thread_id only makes sense if we're replying in
|
||||
# the same chat.
|
||||
return self.message_thread_id if chat_id in {self.chat_id, self.chat.username} else None
|
||||
|
||||
async def reply_text(
|
||||
self,
|
||||
@@ -1601,9 +1653,10 @@ class Message(MaybeInaccessibleMessage):
|
||||
reply_markup: Optional[ReplyMarkup] = None,
|
||||
entities: Optional[Sequence["MessageEntity"]] = None,
|
||||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
message_thread_id: Optional[int] = None,
|
||||
message_thread_id: ODVInput[int] = DEFAULT_NONE,
|
||||
link_preview_options: ODVInput["LinkPreviewOptions"] = DEFAULT_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,
|
||||
@@ -1668,6 +1721,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
business_connection_id=self.business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def reply_markdown(
|
||||
@@ -1677,9 +1731,10 @@ class Message(MaybeInaccessibleMessage):
|
||||
reply_markup: Optional[ReplyMarkup] = None,
|
||||
entities: Optional[Sequence["MessageEntity"]] = None,
|
||||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
message_thread_id: Optional[int] = None,
|
||||
message_thread_id: ODVInput[int] = DEFAULT_NONE,
|
||||
link_preview_options: ODVInput["LinkPreviewOptions"] = DEFAULT_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,
|
||||
@@ -1750,6 +1805,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
business_connection_id=self.business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def reply_markdown_v2(
|
||||
@@ -1759,9 +1815,10 @@ class Message(MaybeInaccessibleMessage):
|
||||
reply_markup: Optional[ReplyMarkup] = None,
|
||||
entities: Optional[Sequence["MessageEntity"]] = None,
|
||||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
message_thread_id: Optional[int] = None,
|
||||
message_thread_id: ODVInput[int] = DEFAULT_NONE,
|
||||
link_preview_options: ODVInput["LinkPreviewOptions"] = DEFAULT_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,
|
||||
@@ -1828,6 +1885,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
business_connection_id=self.business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def reply_html(
|
||||
@@ -1837,9 +1895,10 @@ class Message(MaybeInaccessibleMessage):
|
||||
reply_markup: Optional[ReplyMarkup] = None,
|
||||
entities: Optional[Sequence["MessageEntity"]] = None,
|
||||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
message_thread_id: Optional[int] = None,
|
||||
message_thread_id: ODVInput[int] = DEFAULT_NONE,
|
||||
link_preview_options: ODVInput["LinkPreviewOptions"] = DEFAULT_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,
|
||||
@@ -1906,6 +1965,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
business_connection_id=self.business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def reply_media_group(
|
||||
@@ -1915,8 +1975,9 @@ class Message(MaybeInaccessibleMessage):
|
||||
],
|
||||
disable_notification: ODVInput[bool] = DEFAULT_NONE,
|
||||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
message_thread_id: Optional[int] = None,
|
||||
message_thread_id: ODVInput[int] = DEFAULT_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,
|
||||
@@ -1983,6 +2044,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
parse_mode=parse_mode,
|
||||
caption_entities=caption_entities,
|
||||
business_connection_id=self.business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def reply_photo(
|
||||
@@ -1994,9 +2056,11 @@ class Message(MaybeInaccessibleMessage):
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Optional[Sequence["MessageEntity"]] = None,
|
||||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
message_thread_id: Optional[int] = None,
|
||||
message_thread_id: ODVInput[int] = DEFAULT_NONE,
|
||||
has_spoiler: Optional[bool] = None,
|
||||
reply_parameters: Optional["ReplyParameters"] = 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,
|
||||
@@ -2062,6 +2126,8 @@ class Message(MaybeInaccessibleMessage):
|
||||
api_kwargs=api_kwargs,
|
||||
has_spoiler=has_spoiler,
|
||||
business_connection_id=self.business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
show_caption_above_media=show_caption_above_media,
|
||||
)
|
||||
|
||||
async def reply_audio(
|
||||
@@ -2076,9 +2142,10 @@ class Message(MaybeInaccessibleMessage):
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Optional[Sequence["MessageEntity"]] = None,
|
||||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
message_thread_id: Optional[int] = None,
|
||||
message_thread_id: ODVInput[int] = DEFAULT_NONE,
|
||||
thumbnail: Optional[FileInput] = 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,
|
||||
@@ -2147,6 +2214,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
api_kwargs=api_kwargs,
|
||||
thumbnail=thumbnail,
|
||||
business_connection_id=self.business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def reply_document(
|
||||
@@ -2159,9 +2227,10 @@ class Message(MaybeInaccessibleMessage):
|
||||
disable_content_type_detection: Optional[bool] = None,
|
||||
caption_entities: Optional[Sequence["MessageEntity"]] = None,
|
||||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
message_thread_id: Optional[int] = None,
|
||||
message_thread_id: ODVInput[int] = DEFAULT_NONE,
|
||||
thumbnail: Optional[FileInput] = 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,
|
||||
@@ -2228,6 +2297,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
message_thread_id=message_thread_id,
|
||||
thumbnail=thumbnail,
|
||||
business_connection_id=self.business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def reply_animation(
|
||||
@@ -2242,10 +2312,12 @@ class Message(MaybeInaccessibleMessage):
|
||||
reply_markup: Optional[ReplyMarkup] = None,
|
||||
caption_entities: Optional[Sequence["MessageEntity"]] = None,
|
||||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
message_thread_id: Optional[int] = None,
|
||||
message_thread_id: ODVInput[int] = DEFAULT_NONE,
|
||||
has_spoiler: Optional[bool] = None,
|
||||
thumbnail: Optional[FileInput] = None,
|
||||
reply_parameters: Optional["ReplyParameters"] = 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,
|
||||
@@ -2315,6 +2387,8 @@ class Message(MaybeInaccessibleMessage):
|
||||
has_spoiler=has_spoiler,
|
||||
thumbnail=thumbnail,
|
||||
business_connection_id=self.business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
show_caption_above_media=show_caption_above_media,
|
||||
)
|
||||
|
||||
async def reply_sticker(
|
||||
@@ -2323,9 +2397,10 @@ class Message(MaybeInaccessibleMessage):
|
||||
disable_notification: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_markup: Optional[ReplyMarkup] = None,
|
||||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
message_thread_id: Optional[int] = None,
|
||||
message_thread_id: ODVInput[int] = DEFAULT_NONE,
|
||||
emoji: Optional[str] = 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,
|
||||
@@ -2386,6 +2461,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
message_thread_id=message_thread_id,
|
||||
emoji=emoji,
|
||||
business_connection_id=self.business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def reply_video(
|
||||
@@ -2401,10 +2477,12 @@ class Message(MaybeInaccessibleMessage):
|
||||
supports_streaming: Optional[bool] = None,
|
||||
caption_entities: Optional[Sequence["MessageEntity"]] = None,
|
||||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
message_thread_id: Optional[int] = None,
|
||||
message_thread_id: ODVInput[int] = DEFAULT_NONE,
|
||||
has_spoiler: Optional[bool] = None,
|
||||
thumbnail: Optional[FileInput] = None,
|
||||
reply_parameters: Optional["ReplyParameters"] = 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,
|
||||
@@ -2475,6 +2553,8 @@ class Message(MaybeInaccessibleMessage):
|
||||
has_spoiler=has_spoiler,
|
||||
thumbnail=thumbnail,
|
||||
business_connection_id=self.business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
show_caption_above_media=show_caption_above_media,
|
||||
)
|
||||
|
||||
async def reply_video_note(
|
||||
@@ -2485,9 +2565,10 @@ class Message(MaybeInaccessibleMessage):
|
||||
disable_notification: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_markup: Optional[ReplyMarkup] = None,
|
||||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
message_thread_id: Optional[int] = None,
|
||||
message_thread_id: ODVInput[int] = DEFAULT_NONE,
|
||||
thumbnail: Optional[FileInput] = 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,
|
||||
@@ -2552,6 +2633,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
message_thread_id=message_thread_id,
|
||||
thumbnail=thumbnail,
|
||||
business_connection_id=self.business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def reply_voice(
|
||||
@@ -2564,8 +2646,9 @@ class Message(MaybeInaccessibleMessage):
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Optional[Sequence["MessageEntity"]] = None,
|
||||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
message_thread_id: Optional[int] = None,
|
||||
message_thread_id: ODVInput[int] = DEFAULT_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,
|
||||
@@ -2631,6 +2714,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
business_connection_id=self.business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def reply_location(
|
||||
@@ -2644,8 +2728,9 @@ class Message(MaybeInaccessibleMessage):
|
||||
heading: Optional[int] = None,
|
||||
proximity_alert_radius: Optional[int] = None,
|
||||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
message_thread_id: Optional[int] = None,
|
||||
message_thread_id: ODVInput[int] = DEFAULT_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,
|
||||
@@ -2712,6 +2797,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
business_connection_id=self.business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def reply_venue(
|
||||
@@ -2727,8 +2813,9 @@ class Message(MaybeInaccessibleMessage):
|
||||
google_place_id: Optional[str] = None,
|
||||
google_place_type: Optional[str] = None,
|
||||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
message_thread_id: Optional[int] = None,
|
||||
message_thread_id: ODVInput[int] = DEFAULT_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,
|
||||
@@ -2797,6 +2884,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
business_connection_id=self.business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def reply_contact(
|
||||
@@ -2808,8 +2896,9 @@ class Message(MaybeInaccessibleMessage):
|
||||
reply_markup: Optional[ReplyMarkup] = None,
|
||||
vcard: Optional[str] = None,
|
||||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
message_thread_id: Optional[int] = None,
|
||||
message_thread_id: ODVInput[int] = DEFAULT_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,
|
||||
@@ -2874,12 +2963,13 @@ class Message(MaybeInaccessibleMessage):
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
business_connection_id=self.business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def reply_poll(
|
||||
self,
|
||||
question: str,
|
||||
options: Sequence[str],
|
||||
options: Sequence[Union[str, "InputPollOption"]],
|
||||
is_anonymous: Optional[bool] = None,
|
||||
type: Optional[str] = None, # pylint: disable=redefined-builtin
|
||||
allows_multiple_answers: Optional[bool] = None,
|
||||
@@ -2893,8 +2983,11 @@ class Message(MaybeInaccessibleMessage):
|
||||
close_date: Optional[Union[int, datetime.datetime]] = None,
|
||||
explanation_entities: Optional[Sequence["MessageEntity"]] = None,
|
||||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
message_thread_id: Optional[int] = None,
|
||||
message_thread_id: ODVInput[int] = DEFAULT_NONE,
|
||||
reply_parameters: Optional["ReplyParameters"] = 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,
|
||||
@@ -2965,6 +3058,9 @@ class Message(MaybeInaccessibleMessage):
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
business_connection_id=self.business_connection_id,
|
||||
question_parse_mode=question_parse_mode,
|
||||
question_entities=question_entities,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def reply_dice(
|
||||
@@ -2973,8 +3069,9 @@ class Message(MaybeInaccessibleMessage):
|
||||
reply_markup: Optional[ReplyMarkup] = None,
|
||||
emoji: Optional[str] = None,
|
||||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
message_thread_id: Optional[int] = None,
|
||||
message_thread_id: ODVInput[int] = DEFAULT_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,
|
||||
@@ -3034,12 +3131,13 @@ class Message(MaybeInaccessibleMessage):
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
business_connection_id=self.business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def reply_chat_action(
|
||||
self,
|
||||
action: str,
|
||||
message_thread_id: Optional[int] = None,
|
||||
message_thread_id: ODVInput[int] = DEFAULT_NONE,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
@@ -3086,8 +3184,9 @@ class Message(MaybeInaccessibleMessage):
|
||||
disable_notification: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_markup: Optional["InlineKeyboardMarkup"] = None,
|
||||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
message_thread_id: Optional[int] = None,
|
||||
message_thread_id: ODVInput[int] = DEFAULT_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,
|
||||
@@ -3149,6 +3248,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
business_connection_id=self.business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def reply_invoice(
|
||||
@@ -3156,7 +3256,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
title: str,
|
||||
description: str,
|
||||
payload: str,
|
||||
provider_token: str,
|
||||
provider_token: Optional[str],
|
||||
currency: str,
|
||||
prices: Sequence["LabeledPrice"],
|
||||
start_parameter: Optional[str] = None,
|
||||
@@ -3177,8 +3277,9 @@ class Message(MaybeInaccessibleMessage):
|
||||
max_tip_amount: Optional[int] = None,
|
||||
suggested_tip_amounts: Optional[Sequence[int]] = None,
|
||||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
message_thread_id: Optional[int] = None,
|
||||
message_thread_id: ODVInput[int] = DEFAULT_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,
|
||||
@@ -3268,6 +3369,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
suggested_tip_amounts=suggested_tip_amounts,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def forward(
|
||||
@@ -3297,7 +3399,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
Note:
|
||||
Since the release of Bot API 5.5 it can be impossible to forward messages from
|
||||
some chats. Use the attributes :attr:`telegram.Message.has_protected_content` and
|
||||
:attr:`telegram.Chat.has_protected_content` to check this.
|
||||
:attr:`telegram.ChatFullInfo.has_protected_content` to check this.
|
||||
|
||||
As a workaround, it is still possible to use :meth:`copy`. However, this
|
||||
behaviour is undocumented and might be changed by Telegram.
|
||||
@@ -3331,6 +3433,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
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,
|
||||
@@ -3375,6 +3478,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
api_kwargs=api_kwargs,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
show_caption_above_media=show_caption_above_media,
|
||||
)
|
||||
|
||||
async def reply_copy(
|
||||
@@ -3387,8 +3491,9 @@ class Message(MaybeInaccessibleMessage):
|
||||
disable_notification: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_markup: Optional[ReplyMarkup] = None,
|
||||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
message_thread_id: Optional[int] = None,
|
||||
message_thread_id: ODVInput[int] = DEFAULT_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,
|
||||
@@ -3452,6 +3557,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
api_kwargs=api_kwargs,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
show_caption_above_media=show_caption_above_media,
|
||||
)
|
||||
|
||||
async def edit_text(
|
||||
@@ -3510,6 +3616,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
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,
|
||||
@@ -3549,6 +3656,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
api_kwargs=api_kwargs,
|
||||
caption_entities=caption_entities,
|
||||
inline_message_id=None,
|
||||
show_caption_above_media=show_caption_above_media,
|
||||
)
|
||||
|
||||
async def edit_media(
|
||||
@@ -3642,6 +3750,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
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,
|
||||
@@ -3683,6 +3792,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
horizontal_accuracy=horizontal_accuracy,
|
||||
heading=heading,
|
||||
proximity_alert_radius=proximity_alert_radius,
|
||||
live_period=live_period,
|
||||
inline_message_id=None,
|
||||
)
|
||||
|
||||
@@ -4173,9 +4283,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
if not self.text:
|
||||
raise RuntimeError("This Message has no 'text'.")
|
||||
|
||||
entity_text = self.text.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.text, entity)
|
||||
|
||||
def parse_caption_entity(self, entity: MessageEntity) -> str:
|
||||
"""Returns the text from a given :class:`telegram.MessageEntity`.
|
||||
@@ -4199,9 +4307,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
if not self.caption:
|
||||
raise RuntimeError("This Message has no 'caption'.")
|
||||
|
||||
entity_text = self.caption.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.caption, entity)
|
||||
|
||||
def parse_entities(self, types: Optional[List[str]] = None) -> Dict[MessageEntity, str]:
|
||||
"""
|
||||
@@ -4226,12 +4332,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
the text that belongs to them, calculated based on UTF-16 codepoints.
|
||||
|
||||
"""
|
||||
if types is None:
|
||||
types = MessageEntity.ALL_TYPES
|
||||
|
||||
return {
|
||||
entity: self.parse_entity(entity) for entity in self.entities if entity.type in types
|
||||
}
|
||||
return parse_message_entities(self.text, self.entities, types=types)
|
||||
|
||||
def parse_caption_entities(
|
||||
self, types: Optional[List[str]] = None
|
||||
@@ -4258,14 +4359,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
the text that belongs to them, calculated based on UTF-16 codepoints.
|
||||
|
||||
"""
|
||||
if types is None:
|
||||
types = MessageEntity.ALL_TYPES
|
||||
|
||||
return {
|
||||
entity: self.parse_caption_entity(entity)
|
||||
for entity in self.caption_entities
|
||||
if entity.type in types
|
||||
}
|
||||
return parse_message_entities(self.caption, self.caption_entities, types=types)
|
||||
|
||||
@classmethod
|
||||
def _parse_html(
|
||||
@@ -4313,6 +4407,8 @@ class Message(MaybeInaccessibleMessage):
|
||||
insert = f'<a href="{escaped_text}">{escaped_text}</a>'
|
||||
elif entity.type == MessageEntity.BLOCKQUOTE:
|
||||
insert = f"<blockquote>{escaped_text}</blockquote>"
|
||||
elif entity.type == MessageEntity.EXPANDABLE_BLOCKQUOTE:
|
||||
insert = f"<blockquote expandable>{escaped_text}</blockquote>"
|
||||
elif entity.type == MessageEntity.BOLD:
|
||||
insert = f"<b>{escaped_text}</b>"
|
||||
elif entity.type == MessageEntity.ITALIC:
|
||||
@@ -4463,11 +4559,12 @@ class Message(MaybeInaccessibleMessage):
|
||||
) -> Optional[str]:
|
||||
if version == 1:
|
||||
for entity_type in (
|
||||
MessageEntity.UNDERLINE,
|
||||
MessageEntity.STRIKETHROUGH,
|
||||
MessageEntity.SPOILER,
|
||||
MessageEntity.EXPANDABLE_BLOCKQUOTE,
|
||||
MessageEntity.BLOCKQUOTE,
|
||||
MessageEntity.CUSTOM_EMOJI,
|
||||
MessageEntity.SPOILER,
|
||||
MessageEntity.STRIKETHROUGH,
|
||||
MessageEntity.UNDERLINE,
|
||||
):
|
||||
if any(entity.type == entity_type for entity in entities):
|
||||
name = entity_type.name.title().replace("_", " ") # type:ignore[attr-defined]
|
||||
@@ -4547,8 +4644,10 @@ class Message(MaybeInaccessibleMessage):
|
||||
insert = f"~{escaped_text}~"
|
||||
elif entity.type == MessageEntity.SPOILER:
|
||||
insert = f"||{escaped_text}||"
|
||||
elif entity.type == MessageEntity.BLOCKQUOTE:
|
||||
elif entity.type in (MessageEntity.BLOCKQUOTE, MessageEntity.EXPANDABLE_BLOCKQUOTE):
|
||||
insert = ">" + "\n>".join(escaped_text.splitlines())
|
||||
if entity.type == MessageEntity.EXPANDABLE_BLOCKQUOTE:
|
||||
insert = f"{insert}||"
|
||||
elif entity.type == MessageEntity.CUSTOM_EMOJI:
|
||||
# This should never be needed because ids are numeric but the documentation
|
||||
# specifically mentions it so here we are
|
||||
|
||||
+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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
+8
-60
@@ -23,12 +23,6 @@ from telegram._files.photosize import PhotoSize
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||
from telegram._utils.types import JSONDict
|
||||
from telegram._utils.warnings import warn
|
||||
from telegram._utils.warnings_transition import (
|
||||
build_deprecation_warning_message,
|
||||
warn_about_deprecated_attr_in_property,
|
||||
)
|
||||
from telegram.warnings import PTBDeprecationWarning
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram._bot import Bot
|
||||
@@ -44,11 +38,14 @@ class UsersShared(TelegramObject):
|
||||
|
||||
.. 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
|
||||
:attr:`user_ids`.
|
||||
``user_ids``.
|
||||
|
||||
.. versionremoved:: 21.2
|
||||
Removed the deprecated argument and attribute ``user_ids``.
|
||||
|
||||
Args:
|
||||
request_id (:obj:`int`): Identifier of the request.
|
||||
@@ -57,18 +54,8 @@ class UsersShared(TelegramObject):
|
||||
|
||||
.. versionadded:: 21.1
|
||||
|
||||
.. deprecated:: 21.1
|
||||
In future versions, this argument will become keyword only.
|
||||
user_ids (Sequence[:obj:`int`], optional): 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.
|
||||
|
||||
.. deprecated:: 21.1
|
||||
Bot API 7.2 introduced by :paramref:`users`, replacing this argument. Hence, this
|
||||
argument is now optional and will be removed in future versions.
|
||||
.. versionchanged:: 21.2
|
||||
This argument is now required.
|
||||
|
||||
Attributes:
|
||||
request_id (:obj:`int`): Identifier of the request.
|
||||
@@ -83,31 +70,14 @@ class UsersShared(TelegramObject):
|
||||
def __init__(
|
||||
self,
|
||||
request_id: int,
|
||||
user_ids: Optional[Sequence[int]] = None,
|
||||
users: Optional[Sequence["SharedUser"]] = None,
|
||||
users: Sequence["SharedUser"],
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
self.request_id: int = request_id
|
||||
|
||||
if users is None:
|
||||
raise TypeError("`users` is a required argument since Bot API 7.2")
|
||||
|
||||
self.users: Tuple[SharedUser, ...] = parse_sequence_arg(users)
|
||||
|
||||
if user_ids is not None:
|
||||
warn(
|
||||
build_deprecation_warning_message(
|
||||
deprecated_name="user_ids",
|
||||
new_name="users",
|
||||
object_type="parameter",
|
||||
bot_api_version="7.2",
|
||||
),
|
||||
PTBDeprecationWarning,
|
||||
stacklevel=2,
|
||||
)
|
||||
|
||||
self._id_attrs = (self.request_id, self.users)
|
||||
|
||||
self._freeze()
|
||||
@@ -130,28 +100,6 @@ class UsersShared(TelegramObject):
|
||||
|
||||
return super()._de_json(data=data, bot=bot, api_kwargs=api_kwargs)
|
||||
|
||||
@property
|
||||
def user_ids(self) -> Tuple[int, ...]:
|
||||
"""
|
||||
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.
|
||||
|
||||
.. deprecated:: 21.1
|
||||
As Bot API 7.2 replaces this attribute with :attr:`users`, this attribute will be
|
||||
removed in future versions.
|
||||
"""
|
||||
warn_about_deprecated_attr_in_property(
|
||||
deprecated_attr_name="user_ids",
|
||||
new_attr_name="users",
|
||||
bot_api_version="7.2",
|
||||
stacklevel=2,
|
||||
)
|
||||
return tuple(user.user_id for user in self.users)
|
||||
|
||||
|
||||
class ChatShared(TelegramObject):
|
||||
"""
|
||||
|
||||
+4
-4
@@ -141,8 +141,8 @@ class Update(TelegramObject):
|
||||
|
||||
.. versionadded:: 21.1
|
||||
|
||||
business_message (:class:`telegram.Message`, optional): New non-service message
|
||||
from a connected business account.
|
||||
business_message (:class:`telegram.Message`, optional): New message from a connected
|
||||
business account.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
|
||||
@@ -249,8 +249,8 @@ class Update(TelegramObject):
|
||||
|
||||
.. versionadded:: 21.1
|
||||
|
||||
business_message (:class:`telegram.Message`): Optional. New non-service message
|
||||
from a connected business account.
|
||||
business_message (:class:`telegram.Message`): Optional. New message from a connected
|
||||
business account.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
|
||||
|
||||
+83
-2
@@ -40,6 +40,7 @@ if TYPE_CHECKING:
|
||||
InputMediaDocument,
|
||||
InputMediaPhoto,
|
||||
InputMediaVideo,
|
||||
InputPollOption,
|
||||
LabeledPrice,
|
||||
LinkPreviewOptions,
|
||||
Location,
|
||||
@@ -408,6 +409,7 @@ class User(TelegramObject):
|
||||
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,
|
||||
@@ -451,6 +453,7 @@ class User(TelegramObject):
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def delete_message(
|
||||
@@ -530,6 +533,8 @@ class User(TelegramObject):
|
||||
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,
|
||||
@@ -574,6 +579,8 @@ class User(TelegramObject):
|
||||
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(
|
||||
@@ -586,6 +593,7 @@ class User(TelegramObject):
|
||||
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,
|
||||
@@ -630,6 +638,7 @@ class User(TelegramObject):
|
||||
parse_mode=parse_mode,
|
||||
caption_entities=caption_entities,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def send_audio(
|
||||
@@ -648,6 +657,7 @@ class User(TelegramObject):
|
||||
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,
|
||||
@@ -695,6 +705,7 @@ class User(TelegramObject):
|
||||
api_kwargs=api_kwargs,
|
||||
thumbnail=thumbnail,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def send_chat_action(
|
||||
@@ -749,6 +760,7 @@ class User(TelegramObject):
|
||||
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,
|
||||
@@ -792,6 +804,7 @@ class User(TelegramObject):
|
||||
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(
|
||||
@@ -803,6 +816,7 @@ class User(TelegramObject):
|
||||
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,
|
||||
@@ -841,6 +855,7 @@ class User(TelegramObject):
|
||||
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(
|
||||
@@ -857,6 +872,7 @@ class User(TelegramObject):
|
||||
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,
|
||||
@@ -902,6 +918,7 @@ class User(TelegramObject):
|
||||
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(
|
||||
@@ -913,6 +930,7 @@ class User(TelegramObject):
|
||||
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,
|
||||
@@ -951,6 +969,7 @@ class User(TelegramObject):
|
||||
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(
|
||||
@@ -958,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,
|
||||
@@ -981,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,
|
||||
@@ -1048,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(
|
||||
@@ -1064,6 +1085,7 @@ class User(TelegramObject):
|
||||
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,
|
||||
@@ -1109,6 +1131,7 @@ class User(TelegramObject):
|
||||
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(
|
||||
@@ -1128,6 +1151,8 @@ class User(TelegramObject):
|
||||
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,
|
||||
@@ -1176,6 +1201,8 @@ class User(TelegramObject):
|
||||
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(
|
||||
@@ -1188,6 +1215,7 @@ class User(TelegramObject):
|
||||
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,
|
||||
@@ -1227,6 +1255,7 @@ class User(TelegramObject):
|
||||
message_thread_id=message_thread_id,
|
||||
emoji=emoji,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def send_video(
|
||||
@@ -1247,6 +1276,8 @@ class User(TelegramObject):
|
||||
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,
|
||||
@@ -1296,6 +1327,8 @@ class User(TelegramObject):
|
||||
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(
|
||||
@@ -1314,6 +1347,7 @@ class User(TelegramObject):
|
||||
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,
|
||||
@@ -1361,6 +1395,7 @@ class User(TelegramObject):
|
||||
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(
|
||||
@@ -1375,6 +1410,7 @@ class User(TelegramObject):
|
||||
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,
|
||||
@@ -1418,6 +1454,7 @@ class User(TelegramObject):
|
||||
message_thread_id=message_thread_id,
|
||||
thumbnail=thumbnail,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def send_voice(
|
||||
@@ -1433,6 +1470,7 @@ class User(TelegramObject):
|
||||
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,
|
||||
@@ -1477,12 +1515,13 @@ class User(TelegramObject):
|
||||
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,
|
||||
@@ -1499,6 +1538,9 @@ class User(TelegramObject):
|
||||
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,
|
||||
@@ -1548,6 +1590,9 @@ class User(TelegramObject):
|
||||
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(
|
||||
@@ -1562,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,
|
||||
@@ -1603,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(
|
||||
@@ -1617,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,
|
||||
@@ -1658,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(
|
||||
@@ -2096,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=1, micro=0, releaselevel="final", serial=0
|
||||
major=21, minor=3, micro=0, releaselevel="final", serial=0
|
||||
)
|
||||
__version__: Final[str] = str(__version_info__)
|
||||
|
||||
|
||||
+144
-34
@@ -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=2)
|
||||
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):
|
||||
@@ -1726,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"
|
||||
@@ -1736,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`.
|
||||
|
||||
@@ -1895,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.
|
||||
@@ -2878,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."""
|
||||
|
||||
@@ -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]]:
|
||||
|
||||
+143
-83
@@ -365,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.
|
||||
@@ -516,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(
|
||||
@@ -670,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:
|
||||
@@ -703,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,
|
||||
@@ -733,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:
|
||||
|
||||
@@ -826,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,
|
||||
)
|
||||
|
||||
@@ -874,9 +907,7 @@ class Application(Generic[BT, CCT, UD, CD, BD, JQ], AsyncContextManager["Applica
|
||||
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
|
||||
@@ -1038,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))
|
||||
@@ -1151,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
|
||||
@@ -1185,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.
|
||||
@@ -1252,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:
|
||||
@@ -1809,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)
|
||||
|
||||
@@ -528,9 +528,11 @@ class ApplicationBuilder(Generic[BT, CCT, UD, CD, BD, JQ]):
|
||||
:class:`ApplicationBuilder`: The same builder with the updated argument.
|
||||
"""
|
||||
warn(
|
||||
"`ApplicationBuilder.proxy_url` is deprecated since version "
|
||||
"20.7. Use `ApplicationBuilder.proxy` instead.",
|
||||
PTBDeprecationWarning,
|
||||
PTBDeprecationWarning(
|
||||
"20.7",
|
||||
"`ApplicationBuilder.proxy_url` is deprecated. Use `ApplicationBuilder.proxy` "
|
||||
"instead.",
|
||||
),
|
||||
stacklevel=2,
|
||||
)
|
||||
return self.proxy(proxy_url)
|
||||
@@ -760,9 +762,11 @@ class ApplicationBuilder(Generic[BT, CCT, UD, CD, BD, JQ]):
|
||||
:class:`ApplicationBuilder`: The same builder with the updated argument.
|
||||
"""
|
||||
warn(
|
||||
"`ApplicationBuilder.get_updates_proxy_url` is deprecated since version "
|
||||
"20.7. Use `ApplicationBuilder.get_updates_proxy` instead.",
|
||||
PTBDeprecationWarning,
|
||||
PTBDeprecationWarning(
|
||||
"20.7",
|
||||
"`ApplicationBuilder.get_updates_proxy_url` is deprecated. Use "
|
||||
"`ApplicationBuilder.get_updates_proxy` instead.",
|
||||
),
|
||||
stacklevel=2,
|
||||
)
|
||||
return self.get_updates_proxy(get_updates_proxy_url)
|
||||
@@ -1334,7 +1338,13 @@ class ApplicationBuilder(Generic[BT, CCT, UD, CD, BD, JQ]):
|
||||
|
||||
Tip:
|
||||
This can be used for custom stop logic that requires to await coroutines, e.g.
|
||||
sending message to a chat before shutting down the bot
|
||||
sending message to a chat before shutting down the bot.
|
||||
|
||||
Hint:
|
||||
The callback will be called only, if :meth:`Application.stop` was indeed called
|
||||
successfully. For example, if the application is stopped early by calling
|
||||
:meth:`Application.stop_running` within :meth:`post_init`, then the set callback will
|
||||
*not* be called.
|
||||
|
||||
Example:
|
||||
.. code::
|
||||
|
||||
@@ -163,7 +163,7 @@ class BasePersistence(Generic[UD, CD, BD], ABC):
|
||||
return self._update_interval
|
||||
|
||||
@update_interval.setter
|
||||
def update_interval(self, value: object) -> NoReturn:
|
||||
def update_interval(self, _: object) -> NoReturn:
|
||||
raise AttributeError(
|
||||
"You can not assign a new value to update_interval after initialization."
|
||||
)
|
||||
|
||||
@@ -165,7 +165,7 @@ class SimpleUpdateProcessor(BaseUpdateProcessor):
|
||||
|
||||
async def do_process_update(
|
||||
self,
|
||||
update: object,
|
||||
update: object, # noqa: ARG002
|
||||
coroutine: "Awaitable[Any]",
|
||||
) -> None:
|
||||
"""Immediately awaits the coroutine, i.e. does not apply any additional processing.
|
||||
|
||||
@@ -165,7 +165,7 @@ class CallbackContext(Generic[BT, UD, CD, BD]):
|
||||
return self.application.bot_data
|
||||
|
||||
@bot_data.setter
|
||||
def bot_data(self, value: object) -> NoReturn:
|
||||
def bot_data(self, _: object) -> NoReturn:
|
||||
raise AttributeError(
|
||||
f"You can not assign a new value to bot_data, see {_STORING_DATA_WIKI}"
|
||||
)
|
||||
@@ -192,7 +192,7 @@ class CallbackContext(Generic[BT, UD, CD, BD]):
|
||||
return None
|
||||
|
||||
@chat_data.setter
|
||||
def chat_data(self, value: object) -> NoReturn:
|
||||
def chat_data(self, _: object) -> NoReturn:
|
||||
raise AttributeError(
|
||||
f"You can not assign a new value to chat_data, see {_STORING_DATA_WIKI}"
|
||||
)
|
||||
@@ -214,7 +214,7 @@ class CallbackContext(Generic[BT, UD, CD, BD]):
|
||||
return None
|
||||
|
||||
@user_data.setter
|
||||
def user_data(self, value: object) -> NoReturn:
|
||||
def user_data(self, _: object) -> NoReturn:
|
||||
raise AttributeError(
|
||||
f"You can not assign a new value to user_data, see {_STORING_DATA_WIKI}"
|
||||
)
|
||||
|
||||
+54
-20
@@ -156,9 +156,11 @@ class Defaults:
|
||||
raise ValueError("`quote` and `do_quote` are mutually exclusive")
|
||||
if disable_web_page_preview is not None:
|
||||
warn(
|
||||
"`Defaults.disable_web_page_preview` is deprecated. Use "
|
||||
"`Defaults.link_preview_options` instead.",
|
||||
category=PTBDeprecationWarning,
|
||||
PTBDeprecationWarning(
|
||||
"20.8",
|
||||
"`Defaults.disable_web_page_preview` is deprecated. Use "
|
||||
"`Defaults.link_preview_options` instead.",
|
||||
),
|
||||
stacklevel=2,
|
||||
)
|
||||
self._link_preview_options: Optional[LinkPreviewOptions] = LinkPreviewOptions(
|
||||
@@ -169,8 +171,9 @@ class Defaults:
|
||||
|
||||
if quote is not None:
|
||||
warn(
|
||||
"`Defaults.quote` is deprecated. Use `Defaults.do_quote` instead.",
|
||||
category=PTBDeprecationWarning,
|
||||
PTBDeprecationWarning(
|
||||
"20.8", "`Defaults.quote` is deprecated. Use `Defaults.do_quote` instead."
|
||||
),
|
||||
stacklevel=2,
|
||||
)
|
||||
self._do_quote: Optional[bool] = quote
|
||||
@@ -179,13 +182,14 @@ class Defaults:
|
||||
# Gather all defaults that actually have a default value
|
||||
self._api_defaults = {}
|
||||
for kwarg in (
|
||||
"parse_mode",
|
||||
"explanation_parse_mode",
|
||||
"disable_notification",
|
||||
"allow_sending_without_reply",
|
||||
"protect_content",
|
||||
"link_preview_options",
|
||||
"disable_notification",
|
||||
"do_quote",
|
||||
"explanation_parse_mode",
|
||||
"link_preview_options",
|
||||
"parse_mode",
|
||||
"protect_content",
|
||||
"question_parse_mode",
|
||||
):
|
||||
value = getattr(self, kwarg)
|
||||
if value is not None:
|
||||
@@ -235,7 +239,7 @@ class Defaults:
|
||||
return self._parse_mode
|
||||
|
||||
@parse_mode.setter
|
||||
def parse_mode(self, value: object) -> NoReturn:
|
||||
def parse_mode(self, _: object) -> NoReturn:
|
||||
raise AttributeError("You can not assign a new value to parse_mode after initialization.")
|
||||
|
||||
@property
|
||||
@@ -246,7 +250,7 @@ class Defaults:
|
||||
return self._parse_mode
|
||||
|
||||
@explanation_parse_mode.setter
|
||||
def explanation_parse_mode(self, value: object) -> NoReturn:
|
||||
def explanation_parse_mode(self, _: object) -> NoReturn:
|
||||
raise AttributeError(
|
||||
"You can not assign a new value to explanation_parse_mode after initialization."
|
||||
)
|
||||
@@ -259,11 +263,41 @@ class Defaults:
|
||||
return self._parse_mode
|
||||
|
||||
@quote_parse_mode.setter
|
||||
def quote_parse_mode(self, value: object) -> NoReturn:
|
||||
def quote_parse_mode(self, _: object) -> NoReturn:
|
||||
raise AttributeError(
|
||||
"You can not assign a new value to quote_parse_mode after initialization."
|
||||
)
|
||||
|
||||
@property
|
||||
def text_parse_mode(self) -> Optional[str]:
|
||||
""":obj:`str`: Optional. Alias for :attr:`parse_mode`, used for
|
||||
the corresponding parameter of :class:`telegram.InputPollOption`.
|
||||
|
||||
.. versionadded:: 21.2
|
||||
"""
|
||||
return self._parse_mode
|
||||
|
||||
@text_parse_mode.setter
|
||||
def text_parse_mode(self, _: object) -> NoReturn:
|
||||
raise AttributeError(
|
||||
"You can not assign a new value to text_parse_mode after initialization."
|
||||
)
|
||||
|
||||
@property
|
||||
def question_parse_mode(self) -> Optional[str]:
|
||||
""":obj:`str`: Optional. Alias for :attr:`parse_mode`, used for
|
||||
the corresponding parameter of :meth:`telegram.Bot.send_poll`.
|
||||
|
||||
.. versionadded:: 21.2
|
||||
"""
|
||||
return self._parse_mode
|
||||
|
||||
@question_parse_mode.setter
|
||||
def question_parse_mode(self, _: object) -> NoReturn:
|
||||
raise AttributeError(
|
||||
"You can not assign a new value to question_parse_mode after initialization."
|
||||
)
|
||||
|
||||
@property
|
||||
def disable_notification(self) -> Optional[bool]:
|
||||
""":obj:`bool`: Optional. Sends the message silently. Users will
|
||||
@@ -272,7 +306,7 @@ class Defaults:
|
||||
return self._disable_notification
|
||||
|
||||
@disable_notification.setter
|
||||
def disable_notification(self, value: object) -> NoReturn:
|
||||
def disable_notification(self, _: object) -> NoReturn:
|
||||
raise AttributeError(
|
||||
"You can not assign a new value to disable_notification after initialization."
|
||||
)
|
||||
@@ -289,7 +323,7 @@ class Defaults:
|
||||
return self._link_preview_options.is_disabled if self._link_preview_options else None
|
||||
|
||||
@disable_web_page_preview.setter
|
||||
def disable_web_page_preview(self, value: object) -> NoReturn:
|
||||
def disable_web_page_preview(self, _: object) -> NoReturn:
|
||||
raise AttributeError(
|
||||
"You can not assign a new value to disable_web_page_preview after initialization."
|
||||
)
|
||||
@@ -302,7 +336,7 @@ class Defaults:
|
||||
return self._allow_sending_without_reply
|
||||
|
||||
@allow_sending_without_reply.setter
|
||||
def allow_sending_without_reply(self, value: object) -> NoReturn:
|
||||
def allow_sending_without_reply(self, _: object) -> NoReturn:
|
||||
raise AttributeError(
|
||||
"You can not assign a new value to allow_sending_without_reply after initialization."
|
||||
)
|
||||
@@ -318,7 +352,7 @@ class Defaults:
|
||||
return self._do_quote if self._do_quote is not None else None
|
||||
|
||||
@quote.setter
|
||||
def quote(self, value: object) -> NoReturn:
|
||||
def quote(self, _: object) -> NoReturn:
|
||||
raise AttributeError("You can not assign a new value to quote after initialization.")
|
||||
|
||||
@property
|
||||
@@ -329,7 +363,7 @@ class Defaults:
|
||||
return self._tzinfo
|
||||
|
||||
@tzinfo.setter
|
||||
def tzinfo(self, value: object) -> NoReturn:
|
||||
def tzinfo(self, _: object) -> NoReturn:
|
||||
raise AttributeError("You can not assign a new value to tzinfo after initialization.")
|
||||
|
||||
@property
|
||||
@@ -341,7 +375,7 @@ class Defaults:
|
||||
return self._block
|
||||
|
||||
@block.setter
|
||||
def block(self, value: object) -> NoReturn:
|
||||
def block(self, _: object) -> NoReturn:
|
||||
raise AttributeError("You can not assign a new value to block after initialization.")
|
||||
|
||||
@property
|
||||
@@ -354,7 +388,7 @@ class Defaults:
|
||||
return self._protect_content
|
||||
|
||||
@protect_content.setter
|
||||
def protect_content(self, value: object) -> NoReturn:
|
||||
def protect_content(self, _: object) -> NoReturn:
|
||||
raise AttributeError(
|
||||
"You can't assign a new value to protect_content after initialization."
|
||||
)
|
||||
|
||||
+103
-10
@@ -50,8 +50,8 @@ from telegram import (
|
||||
BotShortDescription,
|
||||
BusinessConnection,
|
||||
CallbackQuery,
|
||||
Chat,
|
||||
ChatAdministratorRights,
|
||||
ChatFullInfo,
|
||||
ChatInviteLink,
|
||||
ChatMember,
|
||||
ChatPermissions,
|
||||
@@ -64,6 +64,7 @@ from telegram import (
|
||||
InlineKeyboardMarkup,
|
||||
InlineQueryResultsButton,
|
||||
InputMedia,
|
||||
InputPollOption,
|
||||
LinkPreviewOptions,
|
||||
Location,
|
||||
MaskPosition,
|
||||
@@ -113,7 +114,7 @@ if TYPE_CHECKING:
|
||||
)
|
||||
from telegram.ext import BaseRateLimiter, Defaults
|
||||
|
||||
HandledTypes = TypeVar("HandledTypes", bound=Union[Message, CallbackQuery, Chat])
|
||||
HandledTypes = TypeVar("HandledTypes", bound=Union[Message, CallbackQuery, ChatFullInfo])
|
||||
KT = TypeVar("KT", bound=ReplyMarkup)
|
||||
|
||||
|
||||
@@ -262,7 +263,10 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
|
||||
@classmethod
|
||||
def _warn(
|
||||
cls, message: str, category: Type[Warning] = PTBUserWarning, stacklevel: int = 0
|
||||
cls,
|
||||
message: Union[str, PTBUserWarning],
|
||||
category: Type[Warning] = PTBUserWarning,
|
||||
stacklevel: int = 0,
|
||||
) -> None:
|
||||
"""We override this method to add one more level to the stacklevel, so that the warning
|
||||
points to the user's code, not to the PTB code.
|
||||
@@ -436,6 +440,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
# 3) set the correct parse_mode for all InputMedia objects
|
||||
# 4) handle the LinkPreviewOptions case (see below)
|
||||
# 5) handle the ReplyParameters case (see below)
|
||||
# 6) handle text_parse_mode in InputPollOption
|
||||
for key, val in data.items():
|
||||
# 1)
|
||||
if isinstance(val, DefaultValue):
|
||||
@@ -487,6 +492,21 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
|
||||
data[key] = new_value
|
||||
|
||||
# 6)
|
||||
elif isinstance(val, Sequence) and all(
|
||||
isinstance(obj, InputPollOption) for obj in val
|
||||
):
|
||||
new_val = []
|
||||
for option in val:
|
||||
if not isinstance(option.text_parse_mode, DefaultValue):
|
||||
new_val.append(option)
|
||||
else:
|
||||
new_option = copy(option)
|
||||
with new_option._unfrozen():
|
||||
new_option.text_parse_mode = self.defaults.text_parse_mode
|
||||
new_val.append(new_option)
|
||||
data[key] = new_val
|
||||
|
||||
def _replace_keyboard(self, reply_markup: Optional[KT]) -> Optional[KT]:
|
||||
# If the reply_markup is an inline keyboard and we allow arbitrary callback data, let the
|
||||
# CallbackDataCache build a new keyboard with the data replaced. Otherwise return the input
|
||||
@@ -554,7 +574,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
self.callback_data_cache.process_message(message=obj)
|
||||
return obj # type: ignore[return-value]
|
||||
|
||||
if isinstance(obj, Chat) and obj.pinned_message:
|
||||
if isinstance(obj, ChatFullInfo) and obj.pinned_message:
|
||||
self.callback_data_cache.process_message(obj.pinned_message)
|
||||
|
||||
return obj
|
||||
@@ -573,6 +593,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
link_preview_options: ODVInput["LinkPreviewOptions"] = 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,
|
||||
@@ -604,6 +625,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
if isinstance(result, Message):
|
||||
self._insert_callback_data(result)
|
||||
@@ -778,6 +800,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
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,
|
||||
@@ -808,6 +831,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=self._merge_api_rl_kwargs(api_kwargs, rate_limit_args),
|
||||
show_caption_above_media=show_caption_above_media,
|
||||
)
|
||||
|
||||
async def copy_messages(
|
||||
@@ -853,7 +877,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
pool_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
rate_limit_args: Optional[RLARGS] = None,
|
||||
) -> Chat:
|
||||
) -> ChatFullInfo:
|
||||
# We override this method to call self._insert_callback_data
|
||||
result = await super().get_chat(
|
||||
chat_id=chat_id,
|
||||
@@ -1126,7 +1150,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
title: str,
|
||||
description: str,
|
||||
payload: str,
|
||||
provider_token: str,
|
||||
provider_token: Optional[str],
|
||||
currency: str,
|
||||
prices: Sequence["LabeledPrice"],
|
||||
max_tip_amount: Optional[int] = None,
|
||||
@@ -1185,7 +1209,6 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
name: str,
|
||||
title: str,
|
||||
stickers: Sequence["InputSticker"],
|
||||
sticker_format: Optional[str] = None,
|
||||
sticker_type: Optional[str] = None,
|
||||
needs_repainting: Optional[bool] = None,
|
||||
*,
|
||||
@@ -1201,7 +1224,6 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
name=name,
|
||||
title=title,
|
||||
stickers=stickers,
|
||||
sticker_format=sticker_format,
|
||||
sticker_type=sticker_type,
|
||||
needs_repainting=needs_repainting,
|
||||
read_timeout=read_timeout,
|
||||
@@ -1488,6 +1510,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
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,
|
||||
@@ -1509,6 +1532,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=self._merge_api_rl_kwargs(api_kwargs, rate_limit_args),
|
||||
show_caption_above_media=show_caption_above_media,
|
||||
)
|
||||
|
||||
async def edit_message_live_location(
|
||||
@@ -1522,6 +1546,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
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,
|
||||
@@ -1541,6 +1566,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
horizontal_accuracy=horizontal_accuracy,
|
||||
heading=heading,
|
||||
proximity_alert_radius=proximity_alert_radius,
|
||||
live_period=live_period,
|
||||
location=location,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
@@ -2359,6 +2385,8 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
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,
|
||||
@@ -2395,6 +2423,8 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
business_connection_id=business_connection_id,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=self._merge_api_rl_kwargs(api_kwargs, rate_limit_args),
|
||||
message_effect_id=message_effect_id,
|
||||
show_caption_above_media=show_caption_above_media,
|
||||
)
|
||||
|
||||
async def send_audio(
|
||||
@@ -2414,6 +2444,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
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,
|
||||
@@ -2449,6 +2480,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=self._merge_api_rl_kwargs(api_kwargs, rate_limit_args),
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def send_chat_action(
|
||||
@@ -2490,6 +2522,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
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,
|
||||
@@ -2521,6 +2554,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
pool_timeout=pool_timeout,
|
||||
business_connection_id=business_connection_id,
|
||||
api_kwargs=self._merge_api_rl_kwargs(api_kwargs, rate_limit_args),
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def send_dice(
|
||||
@@ -2533,6 +2567,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
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,
|
||||
@@ -2559,6 +2594,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=self._merge_api_rl_kwargs(api_kwargs, rate_limit_args),
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def send_document(
|
||||
@@ -2576,6 +2612,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
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,
|
||||
@@ -2609,6 +2646,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=self._merge_api_rl_kwargs(api_kwargs, rate_limit_args),
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def send_game(
|
||||
@@ -2621,6 +2659,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
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,
|
||||
@@ -2647,6 +2686,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=self._merge_api_rl_kwargs(api_kwargs, rate_limit_args),
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def send_invoice(
|
||||
@@ -2655,7 +2695,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
title: str,
|
||||
description: str,
|
||||
payload: str,
|
||||
provider_token: str,
|
||||
provider_token: Optional[str],
|
||||
currency: str,
|
||||
prices: Sequence["LabeledPrice"],
|
||||
start_parameter: Optional[str] = None,
|
||||
@@ -2678,6 +2718,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
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,
|
||||
@@ -2723,6 +2764,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=self._merge_api_rl_kwargs(api_kwargs, rate_limit_args),
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def send_location(
|
||||
@@ -2740,6 +2782,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
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,
|
||||
@@ -2773,6 +2816,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
business_connection_id=business_connection_id,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=self._merge_api_rl_kwargs(api_kwargs, rate_limit_args),
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def send_media_group(
|
||||
@@ -2786,6 +2830,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
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,
|
||||
@@ -2817,6 +2862,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
business_connection_id=business_connection_id,
|
||||
parse_mode=parse_mode,
|
||||
caption_entities=caption_entities,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def send_message(
|
||||
@@ -2832,6 +2878,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
link_preview_options: ODVInput["LinkPreviewOptions"] = DEFAULT_NONE,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
message_effect_id: Optional[str] = None,
|
||||
*,
|
||||
disable_web_page_preview: Optional[bool] = None,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
@@ -2863,6 +2910,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=self._merge_api_rl_kwargs(api_kwargs, rate_limit_args),
|
||||
link_preview_options=link_preview_options,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def send_photo(
|
||||
@@ -2879,6 +2927,8 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
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,
|
||||
@@ -2911,13 +2961,15 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=self._merge_api_rl_kwargs(api_kwargs, rate_limit_args),
|
||||
message_effect_id=message_effect_id,
|
||||
show_caption_above_media=show_caption_above_media,
|
||||
)
|
||||
|
||||
async def send_poll(
|
||||
self,
|
||||
chat_id: Union[int, str],
|
||||
question: str,
|
||||
options: Sequence[str],
|
||||
options: Sequence[Union[str, "InputPollOption"]],
|
||||
is_anonymous: Optional[bool] = None,
|
||||
type: Optional[str] = None, # pylint: disable=redefined-builtin
|
||||
allows_multiple_answers: Optional[bool] = None,
|
||||
@@ -2934,6 +2986,9 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
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,
|
||||
@@ -2971,6 +3026,9 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=self._merge_api_rl_kwargs(api_kwargs, rate_limit_args),
|
||||
question_parse_mode=question_parse_mode,
|
||||
question_entities=question_entities,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def send_sticker(
|
||||
@@ -2984,6 +3042,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
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,
|
||||
@@ -3011,6 +3070,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
pool_timeout=pool_timeout,
|
||||
emoji=emoji,
|
||||
api_kwargs=self._merge_api_rl_kwargs(api_kwargs, rate_limit_args),
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def send_venue(
|
||||
@@ -3030,6 +3090,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
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,
|
||||
@@ -3065,6 +3126,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=self._merge_api_rl_kwargs(api_kwargs, rate_limit_args),
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def send_video(
|
||||
@@ -3086,6 +3148,8 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
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,
|
||||
@@ -3123,6 +3187,8 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=self._merge_api_rl_kwargs(api_kwargs, rate_limit_args),
|
||||
message_effect_id=message_effect_id,
|
||||
show_caption_above_media=show_caption_above_media,
|
||||
)
|
||||
|
||||
async def send_video_note(
|
||||
@@ -3138,6 +3204,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
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,
|
||||
@@ -3169,6 +3236,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=self._merge_api_rl_kwargs(api_kwargs, rate_limit_args),
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def send_voice(
|
||||
@@ -3185,6 +3253,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
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,
|
||||
@@ -3217,6 +3286,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=self._merge_api_rl_kwargs(api_kwargs, rate_limit_args),
|
||||
business_connection_id=business_connection_id,
|
||||
message_effect_id=message_effect_id,
|
||||
)
|
||||
|
||||
async def set_chat_administrator_custom_title(
|
||||
@@ -4087,6 +4157,28 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
api_kwargs=self._merge_api_rl_kwargs(api_kwargs, rate_limit_args),
|
||||
)
|
||||
|
||||
async def refund_star_payment(
|
||||
self,
|
||||
user_id: int,
|
||||
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,
|
||||
rate_limit_args: Optional[RLARGS] = None,
|
||||
) -> bool:
|
||||
return await super().refund_star_payment(
|
||||
user_id=user_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=self._merge_api_rl_kwargs(api_kwargs, rate_limit_args),
|
||||
)
|
||||
|
||||
# updated camelCase aliases
|
||||
getMe = get_me
|
||||
sendMessage = send_message
|
||||
@@ -4208,3 +4300,4 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||
setMessageReaction = set_message_reaction
|
||||
getBusinessConnection = get_business_connection
|
||||
replaceStickerInSet = replace_sticker_in_set
|
||||
refundStarPayment = refund_star_payment
|
||||
|
||||
@@ -159,8 +159,8 @@ class CallbackQueryHandler(BaseHandler[Update, CCT]):
|
||||
def collect_additional_context(
|
||||
self,
|
||||
context: CCT,
|
||||
update: Update,
|
||||
application: "Application[Any, CCT, Any, Any, Any, Any]",
|
||||
update: Update, # noqa: ARG002
|
||||
application: "Application[Any, CCT, Any, Any, Any, Any]", # noqa: ARG002
|
||||
check_result: Union[bool, Match[str]],
|
||||
) -> None:
|
||||
"""Add the result of ``re.match(pattern, update.callback_query.data)`` to
|
||||
|
||||
@@ -21,8 +21,9 @@ from typing import Final, Optional, TypeVar
|
||||
|
||||
from telegram import Update
|
||||
from telegram._utils.defaultvalue import DEFAULT_TRUE
|
||||
from telegram._utils.types import DVType
|
||||
from telegram._utils.types import SCT, DVType
|
||||
from telegram.ext._handlers.basehandler import BaseHandler
|
||||
from telegram.ext._utils._update_parsing import parse_chat_id
|
||||
from telegram.ext._utils.types import CCT, HandlerCallback
|
||||
|
||||
RT = TypeVar("RT")
|
||||
@@ -58,6 +59,9 @@ class ChatMemberHandler(BaseHandler[Update, CCT]):
|
||||
:meth:`telegram.ext.Application.process_update`. Defaults to :obj:`True`.
|
||||
|
||||
.. seealso:: :wiki:`Concurrency`
|
||||
chat_id (:obj:`int` | Collection[:obj:`int`], optional): Filters chat member updates from
|
||||
specified chat ID(s) only.
|
||||
.. versionadded:: 21.3
|
||||
|
||||
Attributes:
|
||||
callback (:term:`coroutine function`): The callback function for this handler.
|
||||
@@ -70,7 +74,10 @@ class ChatMemberHandler(BaseHandler[Update, CCT]):
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = ("chat_member_types",)
|
||||
__slots__ = (
|
||||
"_chat_ids",
|
||||
"chat_member_types",
|
||||
)
|
||||
MY_CHAT_MEMBER: Final[int] = -1
|
||||
""":obj:`int`: Used as a constant to handle only :attr:`telegram.Update.my_chat_member`."""
|
||||
CHAT_MEMBER: Final[int] = 0
|
||||
@@ -84,10 +91,12 @@ class ChatMemberHandler(BaseHandler[Update, CCT]):
|
||||
callback: HandlerCallback[Update, CCT, RT],
|
||||
chat_member_types: int = MY_CHAT_MEMBER,
|
||||
block: DVType[bool] = DEFAULT_TRUE,
|
||||
chat_id: Optional[SCT[int]] = None,
|
||||
):
|
||||
super().__init__(callback, block=block)
|
||||
|
||||
self.chat_member_types: Optional[int] = chat_member_types
|
||||
self._chat_ids = parse_chat_id(chat_id)
|
||||
|
||||
def check_update(self, update: object) -> bool:
|
||||
"""Determines whether an update should be passed to this handler's :attr:`callback`.
|
||||
@@ -99,12 +108,18 @@ class ChatMemberHandler(BaseHandler[Update, CCT]):
|
||||
:obj:`bool`
|
||||
|
||||
"""
|
||||
if isinstance(update, Update):
|
||||
if not (update.my_chat_member or update.chat_member):
|
||||
return False
|
||||
if self.chat_member_types == self.ANY_CHAT_MEMBER:
|
||||
return True
|
||||
if self.chat_member_types == self.CHAT_MEMBER:
|
||||
return bool(update.chat_member)
|
||||
return bool(update.my_chat_member)
|
||||
return False
|
||||
if not isinstance(update, Update):
|
||||
return False
|
||||
if not (update.my_chat_member or update.chat_member):
|
||||
return False
|
||||
if (
|
||||
self._chat_ids
|
||||
and update.effective_chat
|
||||
and update.effective_chat.id not in self._chat_ids
|
||||
):
|
||||
return False
|
||||
if self.chat_member_types == self.ANY_CHAT_MEMBER:
|
||||
return True
|
||||
if self.chat_member_types == self.CHAT_MEMBER:
|
||||
return bool(update.chat_member)
|
||||
return bool(update.my_chat_member)
|
||||
|
||||
@@ -109,8 +109,8 @@ class ChosenInlineResultHandler(BaseHandler[Update, CCT]):
|
||||
def collect_additional_context(
|
||||
self,
|
||||
context: CCT,
|
||||
update: Update,
|
||||
application: "Application[Any, CCT, Any, Any, Any, Any]",
|
||||
update: Update, # noqa: ARG002
|
||||
application: "Application[Any, CCT, Any, Any, Any, Any]", # noqa: ARG002
|
||||
check_result: Union[bool, Match[str]],
|
||||
) -> None:
|
||||
"""This function adds the matched regex pattern result to
|
||||
|
||||
@@ -152,7 +152,6 @@ class CommandHandler(BaseHandler[Update, CCT]):
|
||||
Returns:
|
||||
:obj:`bool`: Whether the args are valid for this handler.
|
||||
"""
|
||||
# pylint: disable=too-many-boolean-expressions
|
||||
return bool(
|
||||
(self.has_args is None)
|
||||
or (self.has_args is True and args)
|
||||
@@ -205,8 +204,8 @@ class CommandHandler(BaseHandler[Update, CCT]):
|
||||
def collect_additional_context(
|
||||
self,
|
||||
context: CCT,
|
||||
update: Update,
|
||||
application: "Application[Any, CCT, Any, Any, Any, Any]",
|
||||
update: Update, # noqa: ARG002
|
||||
application: "Application[Any, CCT, Any, Any, Any, Any]", # noqa: ARG002
|
||||
check_result: Optional[Union[bool, Tuple[List[str], Optional[bool]]]],
|
||||
) -> None:
|
||||
"""Add text after the command to :attr:`CallbackContext.args` as list, split on single
|
||||
|
||||
@@ -473,7 +473,7 @@ class ConversationHandler(BaseHandler[Update, CCT]):
|
||||
return self._entry_points
|
||||
|
||||
@entry_points.setter
|
||||
def entry_points(self, value: object) -> NoReturn:
|
||||
def entry_points(self, _: object) -> NoReturn:
|
||||
raise AttributeError(
|
||||
"You can not assign a new value to entry_points after initialization."
|
||||
)
|
||||
@@ -487,7 +487,7 @@ class ConversationHandler(BaseHandler[Update, CCT]):
|
||||
return self._states
|
||||
|
||||
@states.setter
|
||||
def states(self, value: object) -> NoReturn:
|
||||
def states(self, _: object) -> NoReturn:
|
||||
raise AttributeError("You can not assign a new value to states after initialization.")
|
||||
|
||||
@property
|
||||
@@ -499,7 +499,7 @@ class ConversationHandler(BaseHandler[Update, CCT]):
|
||||
return self._fallbacks
|
||||
|
||||
@fallbacks.setter
|
||||
def fallbacks(self, value: object) -> NoReturn:
|
||||
def fallbacks(self, _: object) -> NoReturn:
|
||||
raise AttributeError("You can not assign a new value to fallbacks after initialization.")
|
||||
|
||||
@property
|
||||
@@ -508,7 +508,7 @@ class ConversationHandler(BaseHandler[Update, CCT]):
|
||||
return self._allow_reentry
|
||||
|
||||
@allow_reentry.setter
|
||||
def allow_reentry(self, value: object) -> NoReturn:
|
||||
def allow_reentry(self, _: object) -> NoReturn:
|
||||
raise AttributeError(
|
||||
"You can not assign a new value to allow_reentry after initialization."
|
||||
)
|
||||
@@ -519,7 +519,7 @@ class ConversationHandler(BaseHandler[Update, CCT]):
|
||||
return self._per_user
|
||||
|
||||
@per_user.setter
|
||||
def per_user(self, value: object) -> NoReturn:
|
||||
def per_user(self, _: object) -> NoReturn:
|
||||
raise AttributeError("You can not assign a new value to per_user after initialization.")
|
||||
|
||||
@property
|
||||
@@ -528,7 +528,7 @@ class ConversationHandler(BaseHandler[Update, CCT]):
|
||||
return self._per_chat
|
||||
|
||||
@per_chat.setter
|
||||
def per_chat(self, value: object) -> NoReturn:
|
||||
def per_chat(self, _: object) -> NoReturn:
|
||||
raise AttributeError("You can not assign a new value to per_chat after initialization.")
|
||||
|
||||
@property
|
||||
@@ -537,7 +537,7 @@ class ConversationHandler(BaseHandler[Update, CCT]):
|
||||
return self._per_message
|
||||
|
||||
@per_message.setter
|
||||
def per_message(self, value: object) -> NoReturn:
|
||||
def per_message(self, _: object) -> NoReturn:
|
||||
raise AttributeError("You can not assign a new value to per_message after initialization.")
|
||||
|
||||
@property
|
||||
@@ -551,7 +551,7 @@ class ConversationHandler(BaseHandler[Update, CCT]):
|
||||
return self._conversation_timeout
|
||||
|
||||
@conversation_timeout.setter
|
||||
def conversation_timeout(self, value: object) -> NoReturn:
|
||||
def conversation_timeout(self, _: object) -> NoReturn:
|
||||
raise AttributeError(
|
||||
"You can not assign a new value to conversation_timeout after initialization."
|
||||
)
|
||||
@@ -562,7 +562,7 @@ class ConversationHandler(BaseHandler[Update, CCT]):
|
||||
return self._name
|
||||
|
||||
@name.setter
|
||||
def name(self, value: object) -> NoReturn:
|
||||
def name(self, _: object) -> NoReturn:
|
||||
raise AttributeError("You can not assign a new value to name after initialization.")
|
||||
|
||||
@property
|
||||
@@ -574,7 +574,7 @@ class ConversationHandler(BaseHandler[Update, CCT]):
|
||||
return self._persistent
|
||||
|
||||
@persistent.setter
|
||||
def persistent(self, value: object) -> NoReturn:
|
||||
def persistent(self, _: object) -> NoReturn:
|
||||
raise AttributeError("You can not assign a new value to persistent after initialization.")
|
||||
|
||||
@property
|
||||
@@ -586,7 +586,7 @@ class ConversationHandler(BaseHandler[Update, CCT]):
|
||||
return self._map_to_parent
|
||||
|
||||
@map_to_parent.setter
|
||||
def map_to_parent(self, value: object) -> NoReturn:
|
||||
def map_to_parent(self, _: object) -> NoReturn:
|
||||
raise AttributeError(
|
||||
"You can not assign a new value to map_to_parent after initialization."
|
||||
)
|
||||
|
||||
@@ -130,8 +130,8 @@ class InlineQueryHandler(BaseHandler[Update, CCT]):
|
||||
def collect_additional_context(
|
||||
self,
|
||||
context: CCT,
|
||||
update: Update,
|
||||
application: "Application[Any, CCT, Any, Any, Any, Any]",
|
||||
update: Update, # noqa: ARG002
|
||||
application: "Application[Any, CCT, Any, Any, Any, Any]", # noqa: ARG002
|
||||
check_result: Optional[Union[bool, Match[str]]],
|
||||
) -> None:
|
||||
"""Add the result of ``re.match(pattern, update.inline_query.query)`` to
|
||||
|
||||
@@ -102,8 +102,8 @@ class MessageHandler(BaseHandler[Update, CCT]):
|
||||
def collect_additional_context(
|
||||
self,
|
||||
context: CCT,
|
||||
update: Update,
|
||||
application: "Application[Any, CCT, Any, Any, Any, Any]",
|
||||
update: Update, # noqa: ARG002
|
||||
application: "Application[Any, CCT, Any, Any, Any, Any]", # noqa: ARG002
|
||||
check_result: Optional[Union[bool, Dict[str, object]]],
|
||||
) -> None:
|
||||
"""Adds possible output of data filters to the :class:`CallbackContext`."""
|
||||
|
||||
@@ -171,8 +171,8 @@ class PrefixHandler(BaseHandler[Update, CCT]):
|
||||
def collect_additional_context(
|
||||
self,
|
||||
context: CCT,
|
||||
update: Update,
|
||||
application: "Application[Any, CCT, Any, Any, Any, Any]",
|
||||
update: Update, # noqa: ARG002
|
||||
application: "Application[Any, CCT, Any, Any, Any, Any]", # noqa: ARG002
|
||||
check_result: Optional[Union[bool, Tuple[List[str], Optional[bool]]]],
|
||||
) -> None:
|
||||
"""Add text after the command to :attr:`CallbackContext.args` as list, split on single
|
||||
|
||||
@@ -49,7 +49,7 @@ class StringCommandHandler(BaseHandler[str, CCT]):
|
||||
called when :meth:`check_update` has determined that an update should be processed by
|
||||
this handler. Callback signature::
|
||||
|
||||
async def callback(update: Update, context: CallbackContext)
|
||||
async def callback(update: str, context: CallbackContext)
|
||||
|
||||
The return value of the callback is usually ignored except for the special case of
|
||||
:class:`telegram.ext.ConversationHandler`.
|
||||
@@ -98,8 +98,8 @@ class StringCommandHandler(BaseHandler[str, CCT]):
|
||||
def collect_additional_context(
|
||||
self,
|
||||
context: CCT,
|
||||
update: str,
|
||||
application: "Application[Any, CCT, Any, Any, Any, Any]",
|
||||
update: str, # noqa: ARG002
|
||||
application: "Application[Any, CCT, Any, Any, Any, Any]", # noqa: ARG002
|
||||
check_result: Optional[List[str]],
|
||||
) -> None:
|
||||
"""Add text after the command to :attr:`CallbackContext.args` as list, split on single
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user