mirror of
https://github.com/python-telegram-bot/python-telegram-bot.git
synced 2026-06-21 08:35:28 +00:00
Compare commits
52 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8c692d1008 | |||
| 970d2ab085 | |||
| 60b439ff42 | |||
| b17b0d248d | |||
| e0f36867cc | |||
| 01f689373c | |||
| 1e05381133 | |||
| a05362c79a | |||
| fbf07bf126 | |||
| 3017bf00a4 | |||
| 374875c786 | |||
| 8f9db63f4f | |||
| 1787586902 | |||
| 9c50a38512 | |||
| 3a49372591 | |||
| e637d1733c | |||
| b89f5d6126 | |||
| 6578c76068 | |||
| a967dbe37a | |||
| af76a8485f | |||
| 8a205b10c0 | |||
| 6d70c56159 | |||
| 0913b859d7 | |||
| c3f17bb18e | |||
| 006a290b7b | |||
| 422993b8ab | |||
| 2ac4e009d0 | |||
| efe1392e73 | |||
| 0a673e8f7e | |||
| 86c8cae40d | |||
| f737702544 | |||
| 06f1da576e | |||
| 7a470d57c8 | |||
| 1714bfd8f6 | |||
| 71e4015e22 | |||
| 52237cf00c | |||
| dba7866aab | |||
| 98bed6f01a | |||
| 42d7c8c477 | |||
| 8018e5ff3f | |||
| c39839b026 | |||
| 4213c12c5b | |||
| 97226b1ae3 | |||
| 146ec54a00 | |||
| df8aae0a38 | |||
| 4ccc80f9c1 | |||
| cfc75bb08b | |||
| 51ef571a07 | |||
| 9ce0f49882 | |||
| 5b1e7399a4 | |||
| a83046e1ec | |||
| 44e8292838 |
@@ -26,7 +26,7 @@ Setting things up
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ pip install -r requirements-all.txt
|
||||
$ pip install -r requirements-dev-all.txt
|
||||
|
||||
|
||||
5. Install pre-commit hooks:
|
||||
@@ -194,7 +194,7 @@ Feel free to copy (parts of) the checklist to the PR description to remind you o
|
||||
- Added or updated documentation for the changed class(es) and/or method(s)
|
||||
- Added the new method(s) to ``_extbot.py``
|
||||
- Added or updated ``bot_methods.rst``
|
||||
- Updated the Bot API version number in all places: ``README.rst`` and ``README_RAW.rst`` (including the badge), as well as ``telegram.constants.BOT_API_VERSION_INFO``
|
||||
- Updated the Bot API version number in all places: ``README.rst`` (including the badge) and ``telegram.constants.BOT_API_VERSION_INFO``
|
||||
- Added logic for arbitrary callback data in :class:`telegram.ext.ExtBot` for new methods that either accept a ``reply_markup`` in some form or have a return type that is/contains :class:`~telegram.Message`
|
||||
|
||||
Documenting
|
||||
@@ -210,13 +210,8 @@ doc strings don't have a separate documentation site they generate, instead, the
|
||||
|
||||
User facing documentation
|
||||
-------------------------
|
||||
We use `sphinx`_ to generate static HTML docs. To build them, first make sure you're running Python 3.9 or above and have the required dependencies:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ pip install -r docs/requirements-docs.txt
|
||||
|
||||
then run the following from the PTB root directory:
|
||||
We use `sphinx`_ to generate static HTML docs. To build them, first make sure you're running Python 3.10 or above and have the required dependencies installed as explained above.
|
||||
Then, run the following from the PTB root directory:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ jobs:
|
||||
|
||||
- name: Fetch Dependabot metadata
|
||||
id: dependabot-metadata
|
||||
uses: dependabot/fetch-metadata@v2.1.0
|
||||
uses: dependabot/fetch-metadata@v2.2.0
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
|
||||
@@ -10,7 +10,7 @@ jobs:
|
||||
runs-on: ${{matrix.os}}
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [3.9]
|
||||
python-version: [3.10]
|
||||
os: [ubuntu-latest]
|
||||
fail-fast: False
|
||||
steps:
|
||||
@@ -22,6 +22,6 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -W ignore -m pip install --upgrade pip
|
||||
python -W ignore -m pip install -r requirements-all.txt
|
||||
python -W ignore -m pip install -r requirements-dev-all.txt
|
||||
- name: Check Links
|
||||
run: sphinx-build docs/source docs/build/html -W --keep-going -j auto -b linkcheck
|
||||
|
||||
@@ -14,7 +14,7 @@ jobs:
|
||||
runs-on: ${{matrix.os}}
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [3.9]
|
||||
python-version: ['3.10']
|
||||
os: [ubuntu-latest]
|
||||
fail-fast: False
|
||||
steps:
|
||||
@@ -28,7 +28,7 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -W ignore -m pip install --upgrade pip
|
||||
python -W ignore -m pip install -r requirements-all.txt
|
||||
python -W ignore -m pip install -r requirements-dev-all.txt
|
||||
- name: Test autogeneration of admonitions
|
||||
run: pytest -v --tb=short tests/docs/admonition_inserter.py
|
||||
- name: Build docs
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
name: Warning maintainers
|
||||
on:
|
||||
pull_request_target:
|
||||
paths:
|
||||
- requirements.txt
|
||||
- requirements-opts.txt
|
||||
- .pre-commit-config.yaml
|
||||
permissions:
|
||||
pull-requests: write
|
||||
jobs:
|
||||
job:
|
||||
runs-on: ubuntu-latest
|
||||
name: about pre-commit and dependency change
|
||||
steps:
|
||||
- name: running the check
|
||||
uses: Poolitzer/notifier-action@master
|
||||
with:
|
||||
notify-message: Hey! Looks like you edited the (optional) requirements or the pre-commit hooks. I'm just a friendly reminder to keep the additional dependencies for the hooks in sync with the requirements :)
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -1,18 +0,0 @@
|
||||
name: Warning maintainers
|
||||
on:
|
||||
pull_request_target:
|
||||
paths:
|
||||
- README.rst
|
||||
- README_RAW.rst
|
||||
permissions:
|
||||
pull-requests: write
|
||||
jobs:
|
||||
job:
|
||||
runs-on: ubuntu-latest
|
||||
name: about readme change
|
||||
steps:
|
||||
- name: running the check
|
||||
uses: Poolitzer/notifier-action@master
|
||||
with:
|
||||
notify-message: Hey! Looks like you edited README.rst or README_RAW.rst. I'm just a friendly reminder to apply relevant changes to both of those files :)
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -0,0 +1,129 @@
|
||||
name: Publish to PyPI
|
||||
|
||||
on:
|
||||
# manually trigger the workflow
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build Distribution
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
TAG: ${{ steps.get_tag.outputs.TAG }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.x"
|
||||
- name: Install pypa/build
|
||||
run: >-
|
||||
python3 -m pip install build --user
|
||||
- name: Build a binary wheel and a source tarball
|
||||
run: python3 -m build
|
||||
- name: Store the distribution packages
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: python-package-distributions
|
||||
path: dist/
|
||||
- name: Get Tag Name
|
||||
id: get_tag
|
||||
run: |
|
||||
pip install .
|
||||
TAG=$(python -c "from telegram import __version__; print(f'v{__version__}')")
|
||||
echo "TAG=$TAG" >> $GITHUB_OUTPUT
|
||||
|
||||
publish-to-pypi:
|
||||
name: Publish to PyPI
|
||||
needs:
|
||||
- build
|
||||
runs-on: ubuntu-latest
|
||||
environment:
|
||||
name: release_pypi
|
||||
url: https://pypi.org/p/python-telegram-bot
|
||||
permissions:
|
||||
id-token: write # IMPORTANT: mandatory for trusted publishing
|
||||
|
||||
steps:
|
||||
- name: Download all the dists
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: python-package-distributions
|
||||
path: dist/
|
||||
- name: Publish to PyPI
|
||||
uses: pypa/gh-action-pypi-publish@release/v1
|
||||
|
||||
compute-signatures:
|
||||
name: Compute SHA1 Sums and Sign with Sigstore
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- publish-to-pypi
|
||||
|
||||
permissions:
|
||||
id-token: write # IMPORTANT: mandatory for sigstore
|
||||
|
||||
steps:
|
||||
- name: Download all the dists
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: python-package-distributions
|
||||
path: dist/
|
||||
- name: Compute SHA1 Sums
|
||||
run: |
|
||||
# Compute SHA1 sum of the distribution packages and save it to a file with the same name,
|
||||
# but with .sha1 extension
|
||||
for file in dist/*; do
|
||||
sha1sum $file > $file.sha1
|
||||
done
|
||||
- name: Sign the dists with Sigstore
|
||||
uses: sigstore/gh-action-sigstore-python@v3.0.0
|
||||
with:
|
||||
inputs: >-
|
||||
./dist/*.tar.gz
|
||||
./dist/*.whl
|
||||
- name: Store the distribution packages and signatures
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: python-package-distributions-and-signatures
|
||||
path: dist/
|
||||
|
||||
github-release:
|
||||
name: Upload to GitHub Release
|
||||
needs:
|
||||
- build
|
||||
- compute-signatures
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
permissions:
|
||||
contents: write # IMPORTANT: mandatory for making GitHub Releases
|
||||
|
||||
steps:
|
||||
- name: Download all the dists
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: python-package-distributions-and-signatures
|
||||
path: dist/
|
||||
- name: Create GitHub Release
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
TAG: ${{ needs.build.outputs.TAG }}
|
||||
# Create a tag and a GitHub Release. The description can be changed later, as for now
|
||||
# we don't define it through this workflow.
|
||||
run: >-
|
||||
gh release create
|
||||
'${{ env.TAG }}'
|
||||
--repo '${{ github.repository }}'
|
||||
--generate-notes
|
||||
- name: Upload artifact signatures to GitHub Release
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
TAG: ${{ needs.build.outputs.TAG }}
|
||||
# Upload to GitHub Release using the `gh` CLI.
|
||||
# `dist/` contains the built packages, and the
|
||||
# sigstore-produced signatures and certificates.
|
||||
run: >-
|
||||
gh release upload
|
||||
'${{ env.TAG }}' dist/**
|
||||
--repo '${{ github.repository }}'
|
||||
@@ -0,0 +1,132 @@
|
||||
name: Publish to Test PyPI
|
||||
|
||||
on:
|
||||
# manually trigger the workflow
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build Distribution
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
TAG: ${{ steps.get_tag.outputs.TAG }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.x"
|
||||
- name: Install pypa/build
|
||||
run: >-
|
||||
python3 -m pip install build --user
|
||||
- name: Build a binary wheel and a source tarball
|
||||
run: python3 -m build
|
||||
- name: Store the distribution packages
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: python-package-distributions
|
||||
path: dist/
|
||||
- name: Get Tag Name
|
||||
id: get_tag
|
||||
run: |
|
||||
pip install .
|
||||
TAG=$(python -c "from telegram import __version__; print(f'v{__version__}')")
|
||||
echo "TAG=$TAG" >> $GITHUB_OUTPUT
|
||||
|
||||
publish-to-test-pypi:
|
||||
name: Publish to Test PyPI
|
||||
needs:
|
||||
- build
|
||||
runs-on: ubuntu-latest
|
||||
environment:
|
||||
name: release_test_pypi
|
||||
url: https://test.pypi.org/p/python-telegram-bot
|
||||
permissions:
|
||||
id-token: write # IMPORTANT: mandatory for trusted publishing
|
||||
|
||||
steps:
|
||||
- name: Download all the dists
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: python-package-distributions
|
||||
path: dist/
|
||||
- name: Publish to Test PyPI
|
||||
uses: pypa/gh-action-pypi-publish@release/v1
|
||||
with:
|
||||
repository-url: https://test.pypi.org/legacy/
|
||||
|
||||
compute-signatures:
|
||||
name: Compute SHA1 Sums and Sign with Sigstore
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- publish-to-test-pypi
|
||||
|
||||
permissions:
|
||||
id-token: write # IMPORTANT: mandatory for sigstore
|
||||
|
||||
steps:
|
||||
- name: Download all the dists
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: python-package-distributions
|
||||
path: dist/
|
||||
- name: Compute SHA1 Sums
|
||||
run: |
|
||||
# Compute SHA1 sum of the distribution packages and save it to a file with the same name,
|
||||
# but with .sha1 extension
|
||||
for file in dist/*; do
|
||||
sha1sum $file > $file.sha1
|
||||
done
|
||||
- name: Sign the dists with Sigstore
|
||||
uses: sigstore/gh-action-sigstore-python@v3.0.0
|
||||
with:
|
||||
inputs: >-
|
||||
./dist/*.tar.gz
|
||||
./dist/*.whl
|
||||
- name: Store the distribution packages and signatures
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: python-package-distributions-and-signatures
|
||||
path: dist/
|
||||
|
||||
github-test-release:
|
||||
name: Upload to GitHub Release Draft
|
||||
needs:
|
||||
- build
|
||||
- compute-signatures
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
permissions:
|
||||
contents: write # IMPORTANT: mandatory for making GitHub Releases
|
||||
|
||||
steps:
|
||||
- name: Download all the dists
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: python-package-distributions-and-signatures
|
||||
path: dist/
|
||||
- name: Create GitHub Release
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
TAG: ${{ needs.build.outputs.TAG }}
|
||||
# Create a GitHub Release *draft*. The description can be changed later, as for now
|
||||
# we don't define it through this workflow.
|
||||
run: >-
|
||||
gh release create
|
||||
'${{ env.TAG }}'
|
||||
--repo '${{ github.repository }}'
|
||||
--generate-notes
|
||||
--draft
|
||||
- name: Upload artifact signatures to GitHub Release
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
TAG: ${{ needs.build.outputs.TAG }}
|
||||
# Upload to GitHub Release using the `gh` CLI.
|
||||
# `dist/` contains the built packages, and the
|
||||
# sigstore-produced signatures and certificates.
|
||||
run: >-
|
||||
gh release upload
|
||||
'${{ env.TAG }}' dist/**
|
||||
--repo '${{ github.repository }}'
|
||||
@@ -29,9 +29,8 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -W ignore -m pip install --upgrade pip
|
||||
python -W ignore -m pip install -r requirements.txt
|
||||
python -W ignore -m pip install -r requirements-opts.txt
|
||||
python -W ignore -m pip install -r requirements-dev.txt
|
||||
python -W ignore -m pip install .[all]
|
||||
python -W ignore -m pip install -r requirements-unit-tests.txt
|
||||
- name: Compare to official api
|
||||
run: |
|
||||
pytest -v tests/test_official/test_official.py --junit-xml=.test_report_official.xml
|
||||
@@ -42,7 +41,7 @@ jobs:
|
||||
|
||||
- name: Test Summary
|
||||
id: test_summary
|
||||
uses: test-summary/action@v2.3
|
||||
uses: test-summary/action@v2.4
|
||||
if: always() # always run, even if tests fail
|
||||
with:
|
||||
paths: .test_report_official.xml
|
||||
|
||||
@@ -3,8 +3,8 @@ on:
|
||||
pull_request:
|
||||
paths:
|
||||
- telegram/**
|
||||
- requirements.txt
|
||||
- requirements-opts.txt
|
||||
- pyproject.toml
|
||||
- .github/workflows/type_completeness.yml
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
@@ -14,66 +14,8 @@ jobs:
|
||||
name: test-type-completeness
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- run: git fetch --depth=1 # https://github.com/actions/checkout/issues/329#issuecomment-674881489
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v5
|
||||
- uses: Bibo-Joshi/pyright-type-completeness@1.0.0
|
||||
with:
|
||||
python-version: 3.9
|
||||
cache: 'pip'
|
||||
cache-dependency-path: '**/requirements*.txt'
|
||||
- name: Install Pyright
|
||||
run: |
|
||||
python -W ignore -m pip install pyright~=1.1.316
|
||||
- name: Get PR Completeness
|
||||
# Must run before base completeness, as base completeness will checkout the base branch
|
||||
# And we can't go back to the PR branch after that in case the PR is coming from a fork
|
||||
run: |
|
||||
pip install . -U
|
||||
pyright --verifytypes telegram --ignoreexternal --outputjson > pr.json || true
|
||||
pyright --verifytypes telegram --ignoreexternal > pr.readable || true
|
||||
- name: Get Base Completeness
|
||||
run: |
|
||||
git checkout ${{ github.base_ref }}
|
||||
pip install . -U
|
||||
pyright --verifytypes telegram --ignoreexternal --outputjson > base.json || true
|
||||
- name: Compare Completeness
|
||||
uses: jannekem/run-python-script-action@v1
|
||||
with:
|
||||
script: |
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
base = float(
|
||||
json.load(open("base.json", "rb"))["typeCompleteness"]["completenessScore"]
|
||||
)
|
||||
pr = float(
|
||||
json.load(open("pr.json", "rb"))["typeCompleteness"]["completenessScore"]
|
||||
)
|
||||
base_text = f"This PR changes type completeness from {round(base, 3)} to {round(pr, 3)}."
|
||||
|
||||
if base == 0:
|
||||
text = f"Something is broken in the workflow. Reported type completeness is 0. 💥"
|
||||
set_summary(text)
|
||||
print(Path("pr.readable").read_text(encoding="utf-8"))
|
||||
error(text)
|
||||
exit(1)
|
||||
|
||||
if pr < (base - 0.001):
|
||||
text = f"{base_text} ❌"
|
||||
set_summary(text)
|
||||
print(Path("pr.readable").read_text(encoding="utf-8"))
|
||||
error(text)
|
||||
exit(1)
|
||||
elif pr > (base + 0.001):
|
||||
text = f"{base_text} ✨"
|
||||
set_summary(text)
|
||||
if pr < 1:
|
||||
print(Path("pr.readable").read_text(encoding="utf-8"))
|
||||
print(text)
|
||||
else:
|
||||
text = f"{base_text} This is less than 0.1 percentage points. ✅"
|
||||
set_summary(text)
|
||||
print(Path("pr.readable").read_text(encoding="utf-8"))
|
||||
print(text)
|
||||
package-name: telegram
|
||||
python-version: 3.12
|
||||
pyright-version: ~=1.1.367
|
||||
|
||||
@@ -4,9 +4,9 @@ on:
|
||||
paths:
|
||||
- telegram/**
|
||||
- tests/**
|
||||
- requirements.txt
|
||||
- requirements-opts.txt
|
||||
- requirements-dev.txt
|
||||
- .github/workflows/unit_tests.yml
|
||||
- pyproject.toml
|
||||
- requirements-unit-tests.txt
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
@@ -20,7 +20,7 @@ jobs:
|
||||
runs-on: ${{matrix.os}}
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
|
||||
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13.0-rc.1']
|
||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||
fail-fast: False
|
||||
steps:
|
||||
@@ -35,8 +35,8 @@ jobs:
|
||||
run: |
|
||||
python -W ignore -m pip install --upgrade pip
|
||||
python -W ignore -m pip install -U pytest-cov
|
||||
python -W ignore -m pip install -r requirements.txt
|
||||
python -W ignore -m pip install -r requirements-dev.txt
|
||||
python -W ignore -m pip install .
|
||||
python -W ignore -m pip install -r requirements-unit-tests.txt
|
||||
python -W ignore -m pip install pytest-xdist[psutil]
|
||||
|
||||
- name: Test with pytest
|
||||
@@ -65,7 +65,7 @@ jobs:
|
||||
|
||||
# Test the rest
|
||||
export TEST_WITH_OPT_DEPS='true'
|
||||
pip install -r requirements-opts.txt
|
||||
pip install .[all]
|
||||
# `-n auto --dist loadfile` uses pytest-xdist to run each test file on a different CPU
|
||||
# worker. Increasing number of workers has little effect on test duration, but it seems
|
||||
# to increase flakyness, specially on python 3.7 with --dist=loadgroup.
|
||||
@@ -83,7 +83,7 @@ jobs:
|
||||
|
||||
- name: Test Summary
|
||||
id: test_summary
|
||||
uses: test-summary/action@v2.3
|
||||
uses: test-summary/action@v2.4
|
||||
if: always() # always run, even if tests fail
|
||||
with:
|
||||
paths: |
|
||||
|
||||
@@ -92,3 +92,6 @@ telegram.jpg
|
||||
|
||||
# virtual env
|
||||
venv*
|
||||
|
||||
# environment manager:
|
||||
.mise.toml
|
||||
+10
-10
@@ -1,4 +1,4 @@
|
||||
# Make sure that the additional_dependencies here match requirements(-opts).txt
|
||||
# Make sure that the additional_dependencies here match pyproject.toml
|
||||
|
||||
ci:
|
||||
autofix_prs: false
|
||||
@@ -7,7 +7,7 @@ ci:
|
||||
|
||||
repos:
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
rev: 'v0.4.3'
|
||||
rev: 'v0.5.6'
|
||||
hooks:
|
||||
- id: ruff
|
||||
name: ruff
|
||||
@@ -15,7 +15,7 @@ repos:
|
||||
- httpx~=0.27
|
||||
- tornado~=6.4
|
||||
- APScheduler~=3.10.4
|
||||
- cachetools~=5.3.3
|
||||
- cachetools>=5.3.3,<5.5.0
|
||||
- aiolimiter~=1.1.0
|
||||
- repo: https://github.com/psf/black-pre-commit-mirror
|
||||
rev: 24.4.2
|
||||
@@ -25,11 +25,11 @@ repos:
|
||||
- --diff
|
||||
- --check
|
||||
- repo: https://github.com/PyCQA/flake8
|
||||
rev: 7.0.0
|
||||
rev: 7.1.0
|
||||
hooks:
|
||||
- id: flake8
|
||||
- repo: https://github.com/PyCQA/pylint
|
||||
rev: v3.1.0
|
||||
rev: v3.2.4
|
||||
hooks:
|
||||
- id: pylint
|
||||
files: ^(?!(tests|docs)).*\.py$
|
||||
@@ -37,11 +37,11 @@ repos:
|
||||
- httpx~=0.27
|
||||
- tornado~=6.4
|
||||
- APScheduler~=3.10.4
|
||||
- cachetools~=5.3.3
|
||||
- cachetools>=5.3.3,<5.5.0
|
||||
- aiolimiter~=1.1.0
|
||||
- . # this basically does `pip install -e .`
|
||||
- repo: https://github.com/pre-commit/mirrors-mypy
|
||||
rev: v1.10.0
|
||||
rev: v1.10.1
|
||||
hooks:
|
||||
- id: mypy
|
||||
name: mypy-ptb
|
||||
@@ -53,7 +53,7 @@ repos:
|
||||
- httpx~=0.27
|
||||
- tornado~=6.4
|
||||
- APScheduler~=3.10.4
|
||||
- cachetools~=5.3.3
|
||||
- cachetools>=5.3.3,<5.5.0
|
||||
- aiolimiter~=1.1.0
|
||||
- . # this basically does `pip install -e .`
|
||||
- id: mypy
|
||||
@@ -65,10 +65,10 @@ repos:
|
||||
additional_dependencies:
|
||||
- tornado~=6.4
|
||||
- APScheduler~=3.10.4
|
||||
- cachetools~=5.3.3
|
||||
- cachetools>=5.3.3,<5.5.0
|
||||
- . # this basically does `pip install -e .`
|
||||
- repo: https://github.com/asottile/pyupgrade
|
||||
rev: v3.15.2
|
||||
rev: v3.16.0
|
||||
hooks:
|
||||
- id: pyupgrade
|
||||
args:
|
||||
|
||||
@@ -60,6 +60,7 @@ The following wonderful people contributed directly or indirectly to this projec
|
||||
- `Hugo Damer <https://github.com/HakimusGIT>`_
|
||||
- `ihoru <https://github.com/ihoru>`_
|
||||
- `Iulian Onofrei <https://github.com/revolter>`_
|
||||
- `Jainam Oswal <https://github.com/jainamoswal>`_
|
||||
- `Jasmin Bom <https://github.com/jsmnbom>`_
|
||||
- `JASON0916 <https://github.com/JASON0916>`_
|
||||
- `jeffffc <https://github.com/jeffffc>`_
|
||||
@@ -86,6 +87,7 @@ The following wonderful people contributed directly or indirectly to this projec
|
||||
- `Miguel C. R. <https://github.com/MiguelX413>`_
|
||||
- `miles <https://github.com/miles170>`_
|
||||
- `Mischa Krüger <https://github.com/Makman2>`_
|
||||
- `Mohd Yusuf <https://github.com/mohdyusuf2312>`_
|
||||
- `naveenvhegde <https://github.com/naveenvhegde>`_
|
||||
- `neurrone <https://github.com/neurrone>`_
|
||||
- `NikitaPirate <https://github.com/NikitaPirate>`_
|
||||
@@ -96,6 +98,7 @@ The following wonderful people contributed directly or indirectly to this projec
|
||||
- `Oleg Sushchenko <https://github.com/feuillemorte>`_
|
||||
- `Or Bin <https://github.com/OrBin>`_
|
||||
- `overquota <https://github.com/overquota>`_
|
||||
- `Pablo Martinez <https://github.com/elpekenin>`_
|
||||
- `Paradox <https://github.com/paradox70>`_
|
||||
- `Patrick Hofmann <https://github.com/PH89>`_
|
||||
- `Paul Larsen <https://github.com/PaulSonOfLars>`_
|
||||
|
||||
+104
@@ -4,6 +4,110 @@
|
||||
Changelog
|
||||
=========
|
||||
|
||||
Version 21.5
|
||||
============
|
||||
|
||||
*Released 2024-09-01*
|
||||
|
||||
This is the technical changelog for version 21.5. More elaborate release notes can be found in the news channel `@pythontelegrambotchannel <https://t.me/pythontelegrambotchannel>`_.
|
||||
|
||||
Major Changes
|
||||
-------------
|
||||
|
||||
- Full Support for Bot API 7.9 (:pr:`4429`)
|
||||
- Full Support for Bot API 7.8 (:pr:`4408`)
|
||||
|
||||
New Features
|
||||
------------
|
||||
|
||||
- Add ``MessageEntity.shift_entities`` and ``MessageEntity.concatenate`` (:pr:`4376` closes :issue:`4372`)
|
||||
- Add Parameter ``game_pattern`` to ``CallbackQueryHandler`` (:pr:`4353` by `jainamoswal <https://github.com/jainamoswal>`_ closes :issue:`4269`)
|
||||
- Add Parameter ``read_file_handle`` to ``InputFile`` (:pr:`4388` closes :issue:`4339`)
|
||||
|
||||
Documentation Improvements
|
||||
--------------------------
|
||||
|
||||
- Bugfix for "Available In" Admonitions (:pr:`4413`)
|
||||
- Documentation Improvements (:pr:`4400` closes :issue:`4446`, :pr:`4448` by `Palaptin <https://github.com/Palaptin>`_)
|
||||
- Document Return Types of ``RequestData`` Members (:pr:`4396`)
|
||||
- Add Introductory Paragraphs to Telegram Types Subsections (:pr:`4389` by `mohdyusuf2312 <https://github.com/mohdyusuf2312>`_ closes :issue:`4380`)
|
||||
- Start Adapting to RTD Addons (:pr:`4386`)
|
||||
|
||||
Minor and Internal Changes
|
||||
---------------------------
|
||||
|
||||
- Remove Surplus Logging from ``Updater`` Network Loop (:pr:`4432` by `MartinHjelmare <https://github.com/MartinHjelmare>`_)
|
||||
- Add Internal Constants for Encodings (:pr:`4378` by `elpekenin <https://github.com/elpekenin>`_)
|
||||
- Improve PyPI Automation (:pr:`4375` closes :issue:`4373`)
|
||||
- Update Test Suite to New Test Channel Setup (:pr:`4435`)
|
||||
- Improve Fixture Usage in ``test_message.py`` (:pr:`4431` by `Palaptin <https://github.com/Palaptin>`_)
|
||||
- Update Python 3.13 Test Suite to RC1 (:pr:`4415`)
|
||||
- Bump ``ruff`` and Add New Rules (:pr:`4416`)
|
||||
|
||||
Dependency Updates
|
||||
------------------
|
||||
|
||||
- Update ``cachetools`` requirement from <5.5.0,>=5.3.3 to >=5.3.3,<5.6.0 (:pr:`4437`)
|
||||
- Bump ``sphinx`` from 7.4.7 to 8.0.2 and ``furo`` from 2024.7.18 to 2024.8.6 (:pr:`4412`)
|
||||
- Bump ``test-summary/action`` from 2.3 to 2.4 (:pr:`4410`)
|
||||
- Bump ``pytest`` from 8.2.2 to 8.3.2 (:pr:`4403`)
|
||||
- Bump ``dependabot/fetch-metadata`` from 2.1.0 to 2.2.0 (:pr:`4411`)
|
||||
- Update ``cachetools`` requirement from ~=5.3.3 to >=5.3.3,<5.5.0 (:pr:`4390`)
|
||||
- Bump ``sphinx`` from 7.3.7 to 7.4.7 (:pr:`4395`)
|
||||
- Bump ``furo`` from 2024.5.6 to 2024.7.18 (:pr:`4392`)
|
||||
|
||||
Version 21.4
|
||||
============
|
||||
|
||||
*Released 2024-07-12*
|
||||
|
||||
This is the technical changelog for version 21.4. More elaborate release notes can be found in the news channel `@pythontelegrambotchannel <https://t.me/pythontelegrambotchannel>`_.
|
||||
|
||||
Major Changes
|
||||
-------------
|
||||
|
||||
- Full Support for Bot API 7.5 (:pr:`4328`, :pr:`4316`, :pr:`4315`, :pr:`4312` closes :issue:`4310`, :pr:`4311`)
|
||||
- Full Support for Bot API 7.6 (:pr:`4333` closes :issue:`4331`, :pr:`4344`, :pr:`4341`, :pr:`4334`, :pr:`4335`, :pr:`4351`, :pr:`4342`, :pr:`4348`)
|
||||
- Full Support for Bot API 7.7 (:pr:`4356` closes :issue:`4355`)
|
||||
- Drop ``python-telegram-bot-raw`` And Switch to ``pyproject.toml`` Based Packaging (:pr:`4288` closes :issue:`4129` and :issue:`4296`)
|
||||
- Deprecate Inclusion of ``successful_payment`` in ``Message.effective_attachment`` (:pr:`4365` closes :issue:`4350`)
|
||||
|
||||
New Features
|
||||
------------
|
||||
|
||||
- Add Support for Python 3.13 Beta (:pr:`4253`)
|
||||
- Add ``filters.PAID_MEDIA`` (:pr:`4357`)
|
||||
- Log Received Data on Deserialization Errors (:pr:`4304`)
|
||||
- Add ``MessageEntity.adjust_message_entities_to_utf_16`` Utility Function (:pr:`4323` by `Antares0982 <https://github.com/Antares0982>`_ closes :issue:`4319`)
|
||||
- Make Argument ``bot`` of ``TelegramObject.de_json`` Optional (:pr:`4320`)
|
||||
|
||||
Documentation Improvements
|
||||
--------------------------
|
||||
|
||||
- Documentation Improvements (:pr:`4303` closes :issue:`4301`)
|
||||
- Restructure Readme (:pr:`4362`)
|
||||
- Fix Link-Check Workflow (:pr:`4332`)
|
||||
|
||||
Internal Changes
|
||||
----------------
|
||||
|
||||
- Automate PyPI Releases (:pr:`4364` closes :issue:`4318`)
|
||||
- Add ``mise-en-place`` to ``.gitignore`` (:pr:`4300`)
|
||||
- Use a Composite Action for Testing Type Completeness (:pr:`4367`)
|
||||
- Stabilize Some Concurrency Usages in Test Suite (:pr:`4360`)
|
||||
- Add a Test Case for ``MenuButton`` (:pr:`4363`)
|
||||
- Extend ``SuccessfulPayment`` Test (:pr:`4349`)
|
||||
- Small Fixes for ``test_stars.py`` (:pr:`4347`)
|
||||
- Use Python 3.13 Beta 3 in Test Suite (:pr:`4336`)
|
||||
|
||||
Dependency Updates
|
||||
------------------
|
||||
|
||||
- Bump ``ruff`` and Add New Rules (:pr:`4329`)
|
||||
- Bump ``pre-commit`` Hooks to Latest Versions (:pr:`4337`)
|
||||
- Add Lower Bound for ``flaky`` Dependency (:pr:`4322` by `Palaptin <https://github.com/Palaptin>`_)
|
||||
- Bump ``pytest`` from 8.2.1 to 8.2.2 (:pr:`4294`)
|
||||
|
||||
Version 21.3
|
||||
============
|
||||
*Released 2024-06-07*
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
include LICENSE LICENSE.lesser requirements.txt requirements-opts.txt README_RAW.rst telegram/py.typed
|
||||
+48
-23
@@ -11,7 +11,7 @@
|
||||
:target: https://pypi.org/project/python-telegram-bot/
|
||||
:alt: Supported Python versions
|
||||
|
||||
.. image:: https://img.shields.io/badge/Bot%20API-7.4-blue?logo=telegram
|
||||
.. image:: https://img.shields.io/badge/Bot%20API-7.9-blue?logo=telegram
|
||||
:target: https://core.telegram.org/bots/api-changelog
|
||||
:alt: Supported Bot API version
|
||||
|
||||
@@ -66,23 +66,36 @@ We have a vibrant community of developers helping each other in our `Telegram gr
|
||||
*Stay tuned for library updates and new releases on our* `Telegram Channel <https://telegram.me/pythontelegrambotchannel>`_.
|
||||
|
||||
Introduction
|
||||
============
|
||||
------------
|
||||
|
||||
This library provides a pure Python, asynchronous interface for the
|
||||
`Telegram Bot API <https://core.telegram.org/bots/api>`_.
|
||||
It's compatible with Python versions **3.8+**.
|
||||
|
||||
In addition to the pure API implementation, this library features a number of high-level classes to
|
||||
In addition to the pure API implementation, this library features several convenience methods and shortcuts as well as a number of high-level classes to
|
||||
make the development of bots easy and straightforward. These classes are contained in the
|
||||
``telegram.ext`` submodule.
|
||||
|
||||
Telegram API support
|
||||
====================
|
||||
After installing_ the library, be sure to check out the section on `working with PTB`_.
|
||||
|
||||
All types and methods of the Telegram Bot API **7.4** are supported.
|
||||
Telegram API support
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
All types and methods of the Telegram Bot API **7.9** are natively supported by this library.
|
||||
In addition, Bot API functionality not yet natively included can still be used as described `in our wiki <https://github.com/python-telegram-bot/python-telegram-bot/wiki/Bot-API-Forward-Compatibility>`_.
|
||||
|
||||
Notable Features
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
- `Fully asynchronous <https://github.com/python-telegram-bot/python-telegram-bot/wiki/Concurrency>`_
|
||||
- Convenient shortcut methods, e.g. `Message.reply_text <https://docs.python-telegram-bot.org/en/stable/telegram.message.html#telegram.Message.reply_text>`_
|
||||
- `Fully annotated with static type hints <https://github.com/python-telegram-bot/python-telegram-bot/wiki/Type-Checking>`_
|
||||
- `Customizable and extendable interface <https://github.com/python-telegram-bot/python-telegram-bot/wiki/Architecture>`_
|
||||
- Seamless integration with `webhooks <https://github.com/python-telegram-bot/python-telegram-bot/wiki/Webhooks>`_ and `polling <https://docs.python-telegram-bot.org/en/stable/telegram.ext.application.html#telegram.ext.Application.run_polling>`_
|
||||
- `Comprehensive documentation and examples <#working-with-ptb>`_
|
||||
|
||||
Installing
|
||||
==========
|
||||
----------
|
||||
|
||||
You can install or upgrade ``python-telegram-bot`` via
|
||||
|
||||
@@ -98,22 +111,27 @@ You can also install ``python-telegram-bot`` from source, though this is usually
|
||||
|
||||
$ git clone https://github.com/python-telegram-bot/python-telegram-bot
|
||||
$ cd python-telegram-bot
|
||||
$ python setup.py install
|
||||
$ pip install build
|
||||
$ python -m build
|
||||
|
||||
Verifying Releases
|
||||
------------------
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
We sign all the releases with a GPG key.
|
||||
The signatures are uploaded to both the `GitHub releases page <https://github.com/python-telegram-bot/python-telegram-bot/releases>`_ and the `PyPI project <https://pypi.org/project/python-telegram-bot/>`_ and end with a suffix ``.asc``.
|
||||
To enable you to verify that a release file that you downloaded was indeed provided by the ``python-telegram-bot`` team, we have taken the following measures.
|
||||
|
||||
Starting with v21.4, all releases are signed via `sigstore <https://www.sigstore.dev>`_.
|
||||
The corresponding signature files are uploaded to the `GitHub releases page`_.
|
||||
To verify the signature, please install the `sigstore Python client <https://pypi.org/project/sigstore/>`_ and follow the instructions for `verifying signatures from GitHub Actions <https://github.com/sigstore/sigstore-python#signatures-from-github-actions>`_. As input for the ``--repository`` parameter, please use the value ``python-telegram-bot/python-telegram-bot``.
|
||||
|
||||
Earlier releases are signed with a GPG key.
|
||||
The signatures are uploaded to both the `GitHub releases page`_ and the `PyPI project <https://pypi.org/project/python-telegram-bot/>`_ and end with a suffix ``.asc``.
|
||||
Please find the public keys `here <https://github.com/python-telegram-bot/python-telegram-bot/tree/master/public_keys>`_.
|
||||
The keys are named in the format ``<first_version>-<last_version>.gpg`` or ``<first_version>-current.gpg`` if the key is currently being used for new releases.
|
||||
The keys are named in the format ``<first_version>-<last_version>.gpg``.
|
||||
|
||||
In addition, the GitHub release page also contains the sha1 hashes of the release files in the files with the suffix ``.sha1``.
|
||||
|
||||
This allows you to verify that a release file that you downloaded was indeed provided by the ``python-telegram-bot`` team.
|
||||
|
||||
Dependencies & Their Versions
|
||||
-----------------------------
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
``python-telegram-bot`` tries to use as few 3rd party dependencies as possible.
|
||||
However, for some features using a 3rd party library is more sane than implementing the functionality again.
|
||||
@@ -139,7 +157,7 @@ PTB can be installed with optional dependencies:
|
||||
* ``pip install "python-telegram-bot[http2]"`` installs `httpx[http2] <https://www.python-httpx.org/#dependencies>`_. Use this, if you want to use HTTP/2.
|
||||
* ``pip install "python-telegram-bot[rate-limiter]"`` installs `aiolimiter~=1.1.0 <https://aiolimiter.readthedocs.io/en/stable/>`_. Use this, if you want to use ``telegram.ext.AIORateLimiter``.
|
||||
* ``pip install "python-telegram-bot[webhooks]"`` installs the `tornado~=6.4 <https://www.tornadoweb.org/en/stable/>`_ library. Use this, if you want to use ``telegram.ext.Updater.start_webhook``/``telegram.ext.Application.run_webhook``.
|
||||
* ``pip install "python-telegram-bot[callback-data]"`` installs the `cachetools~=5.3.3 <https://cachetools.readthedocs.io/en/latest/>`_ library. Use this, if you want to use `arbitrary callback_data <https://github.com/python-telegram-bot/python-telegram-bot/wiki/Arbitrary-callback_data>`_.
|
||||
* ``pip install "python-telegram-bot[callback-data]"`` installs the `cachetools>=5.3.3,<5.6.0 <https://cachetools.readthedocs.io/en/latest/>`_ library. Use this, if you want to use `arbitrary callback_data <https://github.com/python-telegram-bot/python-telegram-bot/wiki/Arbitrary-callback_data>`_.
|
||||
* ``pip install "python-telegram-bot[job-queue]"`` installs the `APScheduler~=3.10.4 <https://apscheduler.readthedocs.io/en/3.x/>`_ library and enforces `pytz>=2018.6 <https://pypi.org/project/pytz/>`_, where ``pytz`` is a dependency of ``APScheduler``. Use this, if you want to use the ``telegram.ext.JobQueue``.
|
||||
|
||||
To install multiple optional dependencies, separate them by commas, e.g. ``pip install "python-telegram-bot[socks,webhooks]"``.
|
||||
@@ -149,14 +167,19 @@ Additionally, two shortcuts are provided:
|
||||
* ``pip install "python-telegram-bot[all]"`` installs all optional dependencies.
|
||||
* ``pip install "python-telegram-bot[ext]"`` installs all optional dependencies that are related to ``telegram.ext``, i.e. ``[rate-limiter, webhooks, callback-data, job-queue]``.
|
||||
|
||||
Working with PTB
|
||||
----------------
|
||||
|
||||
Once you have installed the library, you can begin working with it - so let's get started!
|
||||
|
||||
Quick Start
|
||||
===========
|
||||
~~~~~~~~~~~
|
||||
|
||||
Our Wiki contains an `Introduction to the API <https://github.com/python-telegram-bot/python-telegram-bot/wiki/Introduction-to-the-API>`_ explaining how the pure Bot API can be accessed via ``python-telegram-bot``.
|
||||
Moreover, the `Tutorial: Your first Bot <https://github.com/python-telegram-bot/python-telegram-bot/wiki/Extensions---Your-first-Bot>`_ gives an introduction on how chatbots can be easily programmed with the help of the ``telegram.ext`` module.
|
||||
|
||||
Resources
|
||||
=========
|
||||
~~~~~~~~~
|
||||
|
||||
- The `package documentation <https://docs.python-telegram-bot.org/>`_ is the technical reference for ``python-telegram-bot``.
|
||||
It contains descriptions of all available classes, modules, methods and arguments as well as the `changelog <https://docs.python-telegram-bot.org/changelog.html>`_.
|
||||
@@ -167,7 +190,7 @@ Resources
|
||||
- The `official Telegram Bot API documentation <https://core.telegram.org/bots/api>`_ is of course always worth a read.
|
||||
|
||||
Getting help
|
||||
============
|
||||
~~~~~~~~~~~~
|
||||
|
||||
If the resources mentioned above don't answer your questions or simply overwhelm you, there are several ways of getting help.
|
||||
|
||||
@@ -178,7 +201,7 @@ If the resources mentioned above don't answer your questions or simply overwhelm
|
||||
3. You can even ask for help on Stack Overflow using the `python-telegram-bot tag <https://stackoverflow.com/questions/tagged/python-telegram-bot>`_.
|
||||
|
||||
Concurrency
|
||||
===========
|
||||
~~~~~~~~~~~
|
||||
|
||||
Since v20.0, ``python-telegram-bot`` is built on top of Pythons ``asyncio`` module.
|
||||
Because ``asyncio`` is in general single-threaded, ``python-telegram-bot`` does currently not aim to be thread-safe.
|
||||
@@ -191,20 +214,22 @@ Noteworthy parts of ``python-telegram-bots`` API that are likely to cause issues
|
||||
* all classes in the ``telegram.ext.filters`` module that allow to add/remove allowed users/chats at runtime
|
||||
|
||||
Contributing
|
||||
============
|
||||
------------
|
||||
|
||||
Contributions of all sizes are welcome.
|
||||
Please review our `contribution guidelines <https://github.com/python-telegram-bot/python-telegram-bot/blob/master/.github/CONTRIBUTING.rst>`_ to get started.
|
||||
You can also help by `reporting bugs or feature requests <https://github.com/python-telegram-bot/python-telegram-bot/issues/new/choose>`_.
|
||||
|
||||
Donating
|
||||
========
|
||||
--------
|
||||
Occasionally we are asked if we accept donations to support the development.
|
||||
While we appreciate the thought, maintaining PTB is our hobby, and we have almost no running costs for it. We therefore have nothing set up to accept donations.
|
||||
If you still want to donate, we kindly ask you to donate to another open source project/initiative of your choice instead.
|
||||
|
||||
License
|
||||
=======
|
||||
-------
|
||||
|
||||
You may copy, distribute and modify the software provided that modifications are described and licensed for free under `LGPL-3 <https://www.gnu.org/licenses/lgpl-3.0.html>`_.
|
||||
Derivatives works (including modifications or anything statically linked to the library) can only be redistributed under LGPL-3, but applications that use the library don't have to be.
|
||||
|
||||
.. _`GitHub releases page`: https://github.com/python-telegram-bot/python-telegram-bot/releases>
|
||||
|
||||
-213
@@ -1,213 +0,0 @@
|
||||
.. image:: https://github.com/python-telegram-bot/logos/blob/master/logo-text/png/ptb-raw-logo-text_768.png?raw=true
|
||||
:align: center
|
||||
:target: https://python-telegram-bot.org
|
||||
:alt: python-telegram-bot-raw Logo
|
||||
|
||||
.. image:: https://img.shields.io/pypi/v/python-telegram-bot-raw.svg
|
||||
:target: https://pypi.org/project/python-telegram-bot-raw/
|
||||
:alt: PyPi Package Version
|
||||
|
||||
.. image:: https://img.shields.io/pypi/pyversions/python-telegram-bot-raw.svg
|
||||
:target: https://pypi.org/project/python-telegram-bot-raw/
|
||||
:alt: Supported Python versions
|
||||
|
||||
.. 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 version
|
||||
|
||||
.. image:: https://img.shields.io/pypi/dm/python-telegram-bot-raw
|
||||
:target: https://pypistats.org/packages/python-telegram-bot-raw
|
||||
:alt: PyPi Package Monthly Download
|
||||
|
||||
.. image:: https://readthedocs.org/projects/python-telegram-bot/badge/?version=stable
|
||||
:target: https://docs.python-telegram-bot.org/
|
||||
:alt: Documentation Status
|
||||
|
||||
.. image:: https://img.shields.io/pypi/l/python-telegram-bot-raw.svg
|
||||
:target: https://www.gnu.org/licenses/lgpl-3.0.html
|
||||
:alt: LGPLv3 License
|
||||
|
||||
.. image:: https://github.com/python-telegram-bot/python-telegram-bot/actions/workflows/unit_tests.yml/badge.svg?branch=master
|
||||
:target: https://github.com/python-telegram-bot/python-telegram-bot/
|
||||
:alt: Github Actions workflow
|
||||
|
||||
.. image:: https://codecov.io/gh/python-telegram-bot/python-telegram-bot/branch/master/graph/badge.svg
|
||||
:target: https://app.codecov.io/gh/python-telegram-bot/python-telegram-bot
|
||||
:alt: Code coverage
|
||||
|
||||
.. image:: https://isitmaintained.com/badge/resolution/python-telegram-bot/python-telegram-bot.svg
|
||||
:target: https://isitmaintained.com/project/python-telegram-bot/python-telegram-bot
|
||||
:alt: Median time to resolve an issue
|
||||
|
||||
.. image:: https://api.codacy.com/project/badge/Grade/99d901eaa09b44b4819aec05c330c968
|
||||
:target: https://app.codacy.com/gh/python-telegram-bot/python-telegram-bot/dashboard
|
||||
:alt: Code quality: Codacy
|
||||
|
||||
.. image:: https://results.pre-commit.ci/badge/github/python-telegram-bot/python-telegram-bot/master.svg
|
||||
:target: https://results.pre-commit.ci/latest/github/python-telegram-bot/python-telegram-bot/master
|
||||
:alt: pre-commit.ci status
|
||||
|
||||
.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
|
||||
:target: https://github.com/psf/black
|
||||
:alt: Code Style: Black
|
||||
|
||||
.. image:: https://img.shields.io/badge/Telegram-Channel-blue.svg?logo=telegram
|
||||
:target: https://t.me/pythontelegrambotchannel
|
||||
:alt: Telegram Channel
|
||||
|
||||
.. image:: https://img.shields.io/badge/Telegram-Group-blue.svg?logo=telegram
|
||||
: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!
|
||||
|
||||
*Stay tuned for library updates and new releases on our* `Telegram Channel <https://telegram.me/pythontelegrambotchannel>`_.
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
This library provides a pure Python, asynchronous interface for the
|
||||
`Telegram Bot API <https://core.telegram.org/bots/api>`_.
|
||||
It's compatible with Python versions **3.8+**.
|
||||
|
||||
``python-telegram-bot-raw`` is part of the `python-telegram-bot <https://python-telegram-bot.org>`_ ecosystem and provides the pure API functionality extracted from PTB. It therefore does not have independent release schedules, changelogs or documentation.
|
||||
|
||||
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.4** are supported.
|
||||
|
||||
Installing
|
||||
==========
|
||||
|
||||
You can install or upgrade ``python-telegram-bot`` via
|
||||
|
||||
.. code:: shell
|
||||
|
||||
$ pip install python-telegram-bot-raw --upgrade
|
||||
|
||||
To install a pre-release, use the ``--pre`` `flag <https://pip.pypa.io/en/stable/cli/pip_install/#cmdoption-pre>`_ in addition.
|
||||
|
||||
You can also install ``python-telegram-bot-raw`` from source, though this is usually not necessary.
|
||||
|
||||
.. code:: shell
|
||||
|
||||
$ git clone https://github.com/python-telegram-bot/python-telegram-bot
|
||||
$ cd python-telegram-bot
|
||||
$ python setup_raw.py install
|
||||
|
||||
Note
|
||||
----
|
||||
|
||||
Installing the ``.tar.gz`` archive available on PyPi directly via ``pip`` will *not* work as expected, as ``pip`` does not recognize that it should use ``setup_raw.py`` instead of ``setup.py``.
|
||||
|
||||
Verifying Releases
|
||||
------------------
|
||||
|
||||
We sign all the releases with a GPG key.
|
||||
The signatures are uploaded to both the `GitHub releases page <https://github.com/python-telegram-bot/python-telegram-bot/releases>`_ and the `PyPI project <https://pypi.org/project/python-telegram-bot/>`_ and end with a suffix ``.asc``.
|
||||
Please find the public keys `here <https://github.com/python-telegram-bot/python-telegram-bot/tree/master/public_keys>`_.
|
||||
The keys are named in the format ``<first_version>-<last_version>.gpg`` or ``<first_version>-current.gpg`` if the key is currently being used for new releases.
|
||||
|
||||
In addition, the GitHub release page also contains the sha1 hashes of the release files in the files with the suffix ``.sha1``.
|
||||
|
||||
This allows you to verify that a release file that you downloaded was indeed provided by the ``python-telegram-bot`` team.
|
||||
|
||||
Dependencies & Their Versions
|
||||
-----------------------------
|
||||
|
||||
``python-telegram-bot`` tries to use as few 3rd party dependencies as possible.
|
||||
However, for some features using a 3rd party library is more sane than implementing the functionality again.
|
||||
As these features are *optional*, the corresponding 3rd party dependencies are not installed by default.
|
||||
Instead, they are listed as optional dependencies.
|
||||
This allows to avoid unnecessary dependency conflicts for users who don't need the optional features.
|
||||
|
||||
The only required dependency is `httpx ~= 0.27 <https://www.python-httpx.org>`_ for
|
||||
``telegram.request.HTTPXRequest``, the default networking backend.
|
||||
|
||||
``python-telegram-bot`` is most useful when used along with additional libraries.
|
||||
To minimize dependency conflicts, we try to be liberal in terms of version requirements on the (optional) dependencies.
|
||||
On the other hand, we have to ensure stability of ``python-telegram-bot``, which is why we do apply version bounds.
|
||||
If you encounter dependency conflicts due to these bounds, feel free to reach out.
|
||||
|
||||
Optional Dependencies
|
||||
#####################
|
||||
|
||||
PTB can be installed with optional dependencies:
|
||||
|
||||
* ``pip install "python-telegram-bot-raw[passport]"`` installs the `cryptography>=39.0.1 <https://cryptography.io/en/stable>`_ library. Use this, if you want to use Telegram Passport related functionality.
|
||||
* ``pip install "python-telegram-bot-raw[socks]"`` installs `httpx[socks] <https://www.python-httpx.org/#dependencies>`_. Use this, if you want to work behind a Socks5 server.
|
||||
* ``pip install "python-telegram-bot-raw[http2]"`` installs `httpx[http2] <https://www.python-httpx.org/#dependencies>`_. Use this, if you want to use HTTP/2.
|
||||
|
||||
To install multiple optional dependencies, separate them by commas, e.g. ``pip install "python-telegram-bot-raw[passport,socks]"``.
|
||||
|
||||
Additionally, the shortcut ``pip install "python-telegram-bot-raw[all]"`` installs all optional dependencies.
|
||||
|
||||
Quick Start
|
||||
===========
|
||||
|
||||
Our Wiki contains an `Introduction to the API <https://github.com/python-telegram-bot/python-telegram-bot/wiki/Introduction-to-the-API>`_ explaining how the pure Bot API can be accessed via ``python-telegram-bot``.
|
||||
|
||||
Resources
|
||||
=========
|
||||
|
||||
- The `package documentation <https://docs.python-telegram-bot.org/>`_ is the technical reference for ``python-telegram-bot``.
|
||||
It contains descriptions of all available classes, modules, methods and arguments as well as the `changelog <https://docs.python-telegram-bot.org/changelog.html>`_.
|
||||
- The `wiki <https://github.com/python-telegram-bot/python-telegram-bot/wiki/>`_ is home to number of more elaborate introductions of the different features of ``python-telegram-bot`` and other useful resources that go beyond the technical documentation.
|
||||
- Our `examples section <https://docs.python-telegram-bot.org/examples.html>`_ contains several examples that showcase the different features of both the Bot API and ``python-telegram-bot``.
|
||||
Even if it is not your approach for learning, please take a look at ``echobot.py``. It is the de facto base for most of the bots out there.
|
||||
The code for these examples is released to the public domain, so you can start by grabbing the code and building on top of it.
|
||||
- The `official Telegram Bot API documentation <https://core.telegram.org/bots/api>`_ is of course always worth a read.
|
||||
|
||||
Getting help
|
||||
============
|
||||
|
||||
If the resources mentioned above don't answer your questions or simply overwhelm you, there are several ways of getting help.
|
||||
|
||||
1. We have a vibrant community of developers helping each other in our `Telegram group <https://telegram.me/pythontelegrambotgroup>`_. Join us! Asking a question here is often the quickest way to get a pointer in the right direction.
|
||||
|
||||
2. Ask questions by opening `a discussion <https://github.com/python-telegram-bot/python-telegram-bot/discussions/new>`_.
|
||||
|
||||
3. You can even ask for help on Stack Overflow using the `python-telegram-bot tag <https://stackoverflow.com/questions/tagged/python-telegram-bot>`_.
|
||||
|
||||
Concurrency
|
||||
===========
|
||||
|
||||
Since v20.0, ``python-telegram-bot`` is built on top of Pythons ``asyncio`` module.
|
||||
Because ``asyncio`` is in general single-threaded, ``python-telegram-bot`` does currently not aim to be thread-safe.
|
||||
|
||||
Contributing
|
||||
============
|
||||
|
||||
Contributions of all sizes are welcome.
|
||||
Please review our `contribution guidelines <https://github.com/python-telegram-bot/python-telegram-bot/blob/master/.github/CONTRIBUTING.rst>`_ to get started.
|
||||
You can also help by `reporting bugs or feature requests <https://github.com/python-telegram-bot/python-telegram-bot/issues/new/choose>`_.
|
||||
|
||||
Donating
|
||||
========
|
||||
Occasionally we are asked if we accept donations to support the development.
|
||||
While we appreciate the thought, maintaining PTB is our hobby, and we have almost no running costs for it. We therefore have nothing set up to accept donations.
|
||||
If you still want to donate, we kindly ask you to donate to another open source project/initiative of your choice instead.
|
||||
|
||||
License
|
||||
=======
|
||||
|
||||
You may copy, distribute and modify the software provided that modifications are described and licensed for free under `LGPL-3 <https://www.gnu.org/licenses/lgpl-3.0.html>`_.
|
||||
Derivatives works (including modifications or anything statically linked to the library) can only be redistributed under LGPL-3, but applications that use the library don't have to be.
|
||||
@@ -140,7 +140,7 @@ class AdmonitionInserter:
|
||||
r"^\s*(?P<attr_name>[a-z_]+)" # Any number of spaces, named group for attribute
|
||||
r"\s?\(" # Optional whitespace, opening parenthesis
|
||||
r".*" # Any number of characters (that could denote a built-in type)
|
||||
r":class:`.+`" # Marker of a classref, class name in backticks
|
||||
r":(class|obj):`.+`" # Marker of a classref, class name in backticks
|
||||
r".*\):" # Any number of characters, closing parenthesis, colon.
|
||||
# The ^ colon above along with parenthesis is important because it makes sure that
|
||||
# the class is mentioned in the attribute description, not in free text.
|
||||
@@ -149,11 +149,11 @@ class AdmonitionInserter:
|
||||
)
|
||||
|
||||
# for properties: there is no attr name in docstring. Just check if there's a class name.
|
||||
prop_docstring_pattern = re.compile(r":class:`.+`.*:")
|
||||
prop_docstring_pattern = re.compile(r":(class|obj):`.+`.*:")
|
||||
|
||||
# pattern for iterating over potentially many class names in docstring for one attribute.
|
||||
# Tilde is optional (sometimes it is in the docstring, sometimes not).
|
||||
single_class_name_pattern = re.compile(r":class:`~?(?P<class_name>[\w.]*)`")
|
||||
single_class_name_pattern = re.compile(r":(class|obj):`~?(?P<class_name>[\w.]*)`")
|
||||
|
||||
classes_to_inspect = inspect.getmembers(telegram, inspect.isclass) + inspect.getmembers(
|
||||
telegram.ext, inspect.isclass
|
||||
@@ -366,6 +366,7 @@ class AdmonitionInserter:
|
||||
# to ".. admonition: Examples":
|
||||
".. admonition:: Examples",
|
||||
".. version",
|
||||
"Args:",
|
||||
# The space after ":param" is important because docstring can contain
|
||||
# ":paramref:" in its plain text in the beginning of a line (e.g. ExtBot):
|
||||
":param ",
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
import collections.abc
|
||||
import contextlib
|
||||
import inspect
|
||||
import re
|
||||
import typing
|
||||
@@ -153,13 +154,11 @@ def autodoc_process_docstring(
|
||||
if isinstance(obj, telegram.ext.filters.BaseFilter):
|
||||
obj = obj.__class__
|
||||
|
||||
try:
|
||||
with contextlib.suppress(Exception):
|
||||
source_lines, start_line = inspect.getsourcelines(obj)
|
||||
end_line = start_line + len(source_lines)
|
||||
file = Path(inspect.getsourcefile(obj)).relative_to(FILE_ROOT)
|
||||
LINE_NUMBERS[name] = (file, start_line, end_line)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Since we don't document the `__init__`, we call this manually to have it available for
|
||||
# attributes -- see the note above
|
||||
|
||||
@@ -88,7 +88,6 @@ class TGConstXRefRole(PyXRefRole):
|
||||
refnode.rawsource,
|
||||
CONSTANTS_ROLE,
|
||||
)
|
||||
return title, target
|
||||
except Exception as exc:
|
||||
sphinx_logger.exception(
|
||||
"%s:%d: WARNING: Did not convert reference %s due to an exception.",
|
||||
@@ -98,3 +97,5 @@ class TGConstXRefRole(PyXRefRole):
|
||||
exc_info=exc,
|
||||
)
|
||||
return title, target
|
||||
else:
|
||||
return title, target
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
sphinx==7.3.7
|
||||
furo==2024.5.6
|
||||
sphinx==8.0.2
|
||||
furo==2024.8.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
|
||||
sphinx-copybutton==0.5.2
|
||||
sphinx-inline-tabs==2023.4.21
|
||||
sphinx-inline-tabs==2023.4.21
|
||||
+10
-2
@@ -1,3 +1,4 @@
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
@@ -29,7 +30,7 @@ version = telegram.__version__
|
||||
release = telegram.__version__
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
needs_sphinx = "6.1.3"
|
||||
needs_sphinx = "8.0.2"
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
@@ -251,7 +252,14 @@ htmlhelp_basename = "python-telegram-bot-doc"
|
||||
|
||||
# The base URL which points to the root of the HTML documentation. It is used to indicate the
|
||||
# location of document using The Canonical Link Relation. Default: ''.
|
||||
html_baseurl = "https://docs.python-telegram-bot.org"
|
||||
# Set canonical URL from the Read the Docs Domain
|
||||
html_baseurl = os.environ.get("READTHEDOCS_CANONICAL_URL", "")
|
||||
|
||||
# Tell Jinja2 templates the build is running on Read the Docs
|
||||
html_context = {}
|
||||
if os.environ.get("READTHEDOCS", "") == "True":
|
||||
html_context["READTHEDOCS"] = True
|
||||
|
||||
|
||||
# -- Options for LaTeX output ---------------------------------------------
|
||||
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
- Used for sending media grouped together
|
||||
* - :meth:`~telegram.Bot.send_message`
|
||||
- Used for sending text messages
|
||||
* - :meth:`~telegram.Bot.send_paid_media`
|
||||
- Used for sending paid media to channels
|
||||
* - :meth:`~telegram.Bot.send_photo`
|
||||
- Used for sending photos
|
||||
* - :meth:`~telegram.Bot.send_poll`
|
||||
@@ -369,6 +371,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.get_star_transactions`
|
||||
- Used for obtaining the bot's Telegram Stars transactions
|
||||
* - :meth:`~telegram.Bot.refund_star_payment`
|
||||
- Used for refunding a payment in Telegram Stars
|
||||
|
||||
|
||||
@@ -3,6 +3,18 @@
|
||||
You can adapt this file completely to your liking, but it should at least
|
||||
contain the root `toctree` directive.
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<div style="display: none">
|
||||
|
||||
Hidden Headline
|
||||
===============
|
||||
This is just here to get furo to display the right sidebar.
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</div>
|
||||
|
||||
.. include:: ../../README.rst
|
||||
|
||||
.. The toctrees are hidden such that they don't render on the start page but still include the contents into the documentation.
|
||||
|
||||
@@ -88,6 +88,9 @@ Available Types
|
||||
telegram.inputmediadocument
|
||||
telegram.inputmediaphoto
|
||||
telegram.inputmediavideo
|
||||
telegram.inputpaidmedia
|
||||
telegram.inputpaidmediaphoto
|
||||
telegram.inputpaidmediavideo
|
||||
telegram.inputpolloption
|
||||
telegram.inputsticker
|
||||
telegram.keyboardbutton
|
||||
@@ -113,6 +116,11 @@ Available Types
|
||||
telegram.messageoriginuser
|
||||
telegram.messagereactioncountupdated
|
||||
telegram.messagereactionupdated
|
||||
telegram.paidmedia
|
||||
telegram.paidmediainfo
|
||||
telegram.paidmediaphoto
|
||||
telegram.paidmediapreview
|
||||
telegram.paidmediavideo
|
||||
telegram.photosize
|
||||
telegram.poll
|
||||
telegram.pollanswer
|
||||
@@ -122,6 +130,7 @@ Available Types
|
||||
telegram.reactiontype
|
||||
telegram.reactiontypecustomemoji
|
||||
telegram.reactiontypeemoji
|
||||
telegram.reactiontypepaid
|
||||
telegram.replykeyboardmarkup
|
||||
telegram.replykeyboardremove
|
||||
telegram.replyparameters
|
||||
|
||||
@@ -1,6 +1,21 @@
|
||||
.. _games-tree:
|
||||
|
||||
Games
|
||||
-----
|
||||
|
||||
Your bot can offer users **HTML5 games** to play solo or to compete against each other in groups and one-on-one chats. Create games via `@BotFather <https://telegram.me/BotFather>`_ using the ``/newgame`` command. Please note that this kind of power requires responsibility: you will need to accept the terms for each game that your bots will be offering.
|
||||
|
||||
* Games are a new type of content on Telegram, represented by the :class:`telegram.Game` and :class:`telegram.InlineQueryResultGame` objects.
|
||||
* Once you've created a game via `BotFather <https://t.me/botfather>`_, you can send games to chats as regular messages using the :meth:`~telegram.Bot.sendGame` method, or use :ref:`inline mode <inline-tree>` with :class:`telegram.InlineQueryResultGame`.
|
||||
* If you send the game message without any buttons, it will automatically have a 'Play ``GameName``' button. When this button is pressed, your bot gets a :class:`telegram.CallbackQuery` with the ``game_short_name`` of the requested game. You provide the correct URL for this particular user and the app opens the game in the in-app browser.
|
||||
* You can manually add multiple buttons to your game message. Please note that the first button in the first row **must always** launch the game, using the field ``callback_game`` in :class:`telegram.InlineKeyboardButton`. You can add extra buttons according to taste: e.g., for a description of the rules, or to open the game's official community.
|
||||
* To make your game more attractive, you can upload a GIF animation that demonstrates the game to the users via `BotFather <https://t.me/botfather>`_ (see `Lumberjack <https://t.me/gamebot?game=lumberjack>`_ for example).
|
||||
* A game message will also display high scores for the current chat. Use :meth:`~telegram.Bot.setGameScore` to post high scores to the chat with the game, add the :paramref:`~telegram.Bot.set_game_score.disable_edit_message` parameter to disable automatic update of the message with the current scoreboard.
|
||||
* Use :meth:`~telegram.Bot.getGameHighScores` to get data for in-game high score tables.
|
||||
* You can also add an extra sharing button for users to share their best score to different chats.
|
||||
* For examples of what can be done using this new stuff, check the `@gamebot <https://t.me/gamebot>`_ and `@gamee <https://t.me/gamee>`_ bots.
|
||||
|
||||
|
||||
.. toctree::
|
||||
:titlesonly:
|
||||
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
.. _inline-tree:
|
||||
|
||||
Inline Mode
|
||||
-----------
|
||||
|
||||
The following methods and objects allow your bot to work in `inline mode <https://core.telegram.org/bots/inline>`_.
|
||||
Please see Telegrams `Introduction to Inline bots <https://core.telegram.org/bots/inline>`_ for more details.
|
||||
|
||||
To enable this option, send the ``/setinline`` command to `@BotFather <https://t.me/botfather>`_ and provide the placeholder text that the user will see in the input field after typing your bot's name.
|
||||
|
||||
|
||||
.. toctree::
|
||||
:titlesonly:
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
InputPaidMedia
|
||||
==============
|
||||
|
||||
.. autoclass:: telegram.InputPaidMedia
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,6 @@
|
||||
InputPaidMediaPhoto
|
||||
===================
|
||||
|
||||
.. autoclass:: telegram.InputPaidMediaPhoto
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,6 @@
|
||||
InputPaidMediaVideo
|
||||
===================
|
||||
|
||||
.. autoclass:: telegram.InputPaidMediaVideo
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,6 @@
|
||||
PaidMedia
|
||||
=========
|
||||
|
||||
.. autoclass:: telegram.PaidMedia
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,6 @@
|
||||
PaidMediaInfo
|
||||
=============
|
||||
|
||||
.. autoclass:: telegram.PaidMediaInfo
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,6 @@
|
||||
PaidMediaPhoto
|
||||
==============
|
||||
|
||||
.. autoclass:: telegram.PaidMediaPhoto
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,6 @@
|
||||
PaidMediaPreview
|
||||
================
|
||||
|
||||
.. autoclass:: telegram.PaidMediaPreview
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,6 @@
|
||||
PaidMediaVideo
|
||||
==============
|
||||
|
||||
.. autoclass:: telegram.PaidMediaVideo
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -1,6 +1,9 @@
|
||||
Passport
|
||||
--------
|
||||
|
||||
Passport is a unified authorization method for services that require personal identification. Users can upload their documents once, then instantly share their data with services that require real-world ID (finance, ICOs, etc.). Please see the `manual <https://core.telegram.org/passport>`_ for details.
|
||||
|
||||
|
||||
.. toctree::
|
||||
:titlesonly:
|
||||
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
.. _payments-tree:
|
||||
|
||||
Payments
|
||||
--------
|
||||
|
||||
Your bot can accept payments from Telegram users. Please see the `introduction to payments <https://core.telegram.org/bots/payments>`_ for more details on the process and how to set up payments for your bot.
|
||||
|
||||
|
||||
.. toctree::
|
||||
:titlesonly:
|
||||
|
||||
@@ -8,7 +13,19 @@ Payments
|
||||
telegram.labeledprice
|
||||
telegram.orderinfo
|
||||
telegram.precheckoutquery
|
||||
telegram.refundedpayment
|
||||
telegram.revenuewithdrawalstate
|
||||
telegram.revenuewithdrawalstatefailed
|
||||
telegram.revenuewithdrawalstatepending
|
||||
telegram.revenuewithdrawalstatesucceeded
|
||||
telegram.shippingaddress
|
||||
telegram.shippingoption
|
||||
telegram.shippingquery
|
||||
telegram.startransaction
|
||||
telegram.startransactions
|
||||
telegram.successfulpayment
|
||||
telegram.transactionpartner
|
||||
telegram.transactionpartnerfragment
|
||||
telegram.transactionpartnerother
|
||||
telegram.transactionpartnertelegramads
|
||||
telegram.transactionpartneruser
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
ReactionTypePaid
|
||||
================
|
||||
|
||||
.. autoclass:: telegram.ReactionTypePaid
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,6 @@
|
||||
RefundedPayment
|
||||
===============
|
||||
|
||||
.. autoclass:: telegram.RefundedPayment
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,7 @@
|
||||
RevenueWithdrawalState
|
||||
======================
|
||||
|
||||
.. autoclass:: telegram.RevenueWithdrawalState
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:inherited-members: TelegramObject
|
||||
@@ -0,0 +1,7 @@
|
||||
RevenueWithdrawalStateFailed
|
||||
=============================
|
||||
|
||||
.. autoclass:: telegram.RevenueWithdrawalStateFailed
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:inherited-members: TelegramObject
|
||||
@@ -0,0 +1,7 @@
|
||||
RevenueWithdrawalStatePending
|
||||
=============================
|
||||
|
||||
.. autoclass:: telegram.RevenueWithdrawalStatePending
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:inherited-members: TelegramObject
|
||||
@@ -0,0 +1,7 @@
|
||||
RevenueWithdrawalStateSucceeded
|
||||
===============================
|
||||
|
||||
.. autoclass:: telegram.RevenueWithdrawalStateSucceeded
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:inherited-members: TelegramObject
|
||||
@@ -0,0 +1,7 @@
|
||||
StarTransaction
|
||||
===============
|
||||
|
||||
.. autoclass:: telegram.StarTransaction
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:inherited-members: TelegramObject
|
||||
@@ -0,0 +1,8 @@
|
||||
StarTransactions
|
||||
================
|
||||
|
||||
.. autoclass:: telegram.StarTransactions
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:inherited-members: TelegramObject
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
Stickers
|
||||
--------
|
||||
|
||||
The following methods and objects allow your bot to handle stickers and sticker sets.
|
||||
|
||||
.. toctree::
|
||||
:titlesonly:
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
TransactionPartner
|
||||
==================
|
||||
|
||||
.. autoclass:: telegram.TransactionPartner
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:inherited-members: TelegramObject
|
||||
@@ -0,0 +1,7 @@
|
||||
TransactionPartnerFragment
|
||||
==========================
|
||||
|
||||
.. autoclass:: telegram.TransactionPartnerFragment
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:inherited-members: TelegramObject
|
||||
@@ -0,0 +1,7 @@
|
||||
TransactionPartnerOther
|
||||
=======================
|
||||
|
||||
.. autoclass:: telegram.TransactionPartnerOther
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:inherited-members: TelegramObject
|
||||
@@ -0,0 +1,7 @@
|
||||
TransactionPartnerTelegramAds
|
||||
=============================
|
||||
|
||||
.. autoclass:: telegram.TransactionPartnerTelegramAds
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:inherited-members: TelegramObject
|
||||
@@ -0,0 +1,7 @@
|
||||
TransactionPartnerUser
|
||||
======================
|
||||
|
||||
.. autoclass:: telegram.TransactionPartnerUser
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:inherited-members: TelegramObject
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
.. |editreplymarkup| replace:: It is currently only possible to edit messages without :attr:`telegram.Message.reply_markup` or with inline keyboards.
|
||||
|
||||
.. |bcid_edit_time| replace:: Note that business messages that were not sent by the bot and do not contain an inline keyboard can only be edited within *48 hours* from the time they were sent.
|
||||
|
||||
.. |toapikwargsbase| replace:: These arguments are also considered by :meth:`~telegram.TelegramObject.to_dict` and :meth:`~telegram.TelegramObject.to_json`, i.e. when passing objects to Telegram. Passing them to Telegram is however not guaranteed to work for all kinds of objects, e.g. this will fail for objects that can not directly be JSON serialized.
|
||||
|
||||
.. |toapikwargsarg| replace:: Arbitrary keyword arguments. Can be used to store data for which there are no dedicated attributes. |toapikwargsbase|
|
||||
@@ -58,10 +60,12 @@
|
||||
|
||||
.. |removed_thumb_note| replace:: Removed the deprecated argument and attribute ``thumb``.
|
||||
|
||||
.. |removed_thumb_url_note| replace:: Removed the deprecated argument and attribute ``thumb_url``.
|
||||
.. |removed_thumb_url_note| replace:: Removed the deprecated argument and attribute ``thumb_url`` which made thumbnail_url mandatory.
|
||||
|
||||
.. |removed_thumb_wildcard_note| replace:: Removed the deprecated arguments and attributes ``thumb_*``.
|
||||
|
||||
.. |thumbnail_url_mandatory| replace:: Removal of the deprecated argument ``thumb_url`` made ``thumbnail_url`` mandatory.
|
||||
|
||||
.. |async_context_manager| replace:: Asynchronous context manager which
|
||||
|
||||
.. |reply_parameters| replace:: Description of the message to reply to.
|
||||
@@ -82,6 +86,8 @@
|
||||
|
||||
.. |business_id_str| replace:: Unique identifier of the business connection on behalf of which the message will be sent.
|
||||
|
||||
.. |business_id_str_edit| replace:: Unique identifier of the business connection on behalf of which the message to be edited was 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.
|
||||
|
||||
+10
-10
@@ -47,9 +47,9 @@ async def msg(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
# Files will be downloaded to current directory
|
||||
for data in passport_data.decrypted_data: # This is where the data gets decrypted
|
||||
if data.type == "phone_number":
|
||||
print("Phone: ", data.phone_number)
|
||||
logger.info("Phone: %s", data.phone_number)
|
||||
elif data.type == "email":
|
||||
print("Email: ", data.email)
|
||||
logger.info("Email: %s", data.email)
|
||||
if data.type in (
|
||||
"personal_details",
|
||||
"passport",
|
||||
@@ -58,7 +58,7 @@ async def msg(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"internal_passport",
|
||||
"address",
|
||||
):
|
||||
print(data.type, data.data)
|
||||
logger.info(data.type, data.data)
|
||||
if data.type in (
|
||||
"utility_bill",
|
||||
"bank_statement",
|
||||
@@ -66,28 +66,28 @@ async def msg(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"passport_registration",
|
||||
"temporary_registration",
|
||||
):
|
||||
print(data.type, len(data.files), "files")
|
||||
logger.info(data.type, len(data.files), "files")
|
||||
for file in data.files:
|
||||
actual_file = await file.get_file()
|
||||
print(actual_file)
|
||||
logger.info(actual_file)
|
||||
await actual_file.download_to_drive()
|
||||
if (
|
||||
data.type in ("passport", "driver_license", "identity_card", "internal_passport")
|
||||
and data.front_side
|
||||
):
|
||||
front_file = await data.front_side.get_file()
|
||||
print(data.type, front_file)
|
||||
logger.info(data.type, front_file)
|
||||
await front_file.download_to_drive()
|
||||
if data.type in ("driver_license" and "identity_card") and data.reverse_side:
|
||||
reverse_file = await data.reverse_side.get_file()
|
||||
print(data.type, reverse_file)
|
||||
logger.info(data.type, reverse_file)
|
||||
await reverse_file.download_to_drive()
|
||||
if (
|
||||
data.type in ("passport", "driver_license", "identity_card", "internal_passport")
|
||||
and data.selfie
|
||||
):
|
||||
selfie_file = await data.selfie.get_file()
|
||||
print(data.type, selfie_file)
|
||||
logger.info(data.type, selfie_file)
|
||||
await selfie_file.download_to_drive()
|
||||
if data.translation and data.type in (
|
||||
"passport",
|
||||
@@ -100,10 +100,10 @@ async def msg(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"passport_registration",
|
||||
"temporary_registration",
|
||||
):
|
||||
print(data.type, len(data.translation), "translation")
|
||||
logger.info(data.type, len(data.translation), "translation")
|
||||
for file in data.translation:
|
||||
actual_file = await file.get_file()
|
||||
print(actual_file)
|
||||
logger.info(actual_file)
|
||||
await actual_file.download_to_drive()
|
||||
|
||||
|
||||
|
||||
+122
-8
@@ -1,7 +1,116 @@
|
||||
# PACKAGING
|
||||
[build-system]
|
||||
requires = ["hatchling"]
|
||||
build-backend = "hatchling.build"
|
||||
|
||||
[project]
|
||||
dynamic = ["version"]
|
||||
name = "python-telegram-bot"
|
||||
description = "We have made you a wrapper you can't refuse"
|
||||
readme = "README.rst"
|
||||
requires-python = ">=3.8"
|
||||
license = "LGPL-3.0-only"
|
||||
license-files = { paths = ["LICENSE", "LICENSE.dual", "LICENSE.lesser"] }
|
||||
authors = [
|
||||
{ name = "Leandro Toledo", email = "devs@python-telegram-bot.org" }
|
||||
]
|
||||
keywords = [
|
||||
"python",
|
||||
"telegram",
|
||||
"bot",
|
||||
"api",
|
||||
"wrapper",
|
||||
]
|
||||
classifiers = [
|
||||
"Development Status :: 5 - Production/Stable",
|
||||
"Intended Audience :: Developers",
|
||||
"License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)",
|
||||
"Operating System :: OS Independent",
|
||||
"Topic :: Software Development :: Libraries :: Python Modules",
|
||||
"Topic :: Communications :: Chat",
|
||||
"Topic :: Internet",
|
||||
"Programming Language :: Python",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3.8",
|
||||
"Programming Language :: Python :: 3.9",
|
||||
"Programming Language :: Python :: 3.10",
|
||||
"Programming Language :: Python :: 3.11",
|
||||
"Programming Language :: Python :: 3.12",
|
||||
"Programming Language :: Python :: 3.13",
|
||||
]
|
||||
dependencies = [
|
||||
"httpx ~= 0.27",
|
||||
]
|
||||
|
||||
[project.urls]
|
||||
"Homepage" = "https://python-telegram-bot.org"
|
||||
"Documentation" = "https://docs.python-telegram-bot.org"
|
||||
"Bug Tracker" = "https://github.com/python-telegram-bot/python-telegram-bot/issues"
|
||||
"Source Code" = "https://github.com/python-telegram-bot/python-telegram-bot"
|
||||
"News" = "https://t.me/pythontelegrambotchannel"
|
||||
"Changelog" = "https://docs.python-telegram-bot.org/en/stable/changelog.html"
|
||||
"Support" = "https://t.me/pythontelegrambotgroup"
|
||||
|
||||
[project.optional-dependencies]
|
||||
# Make sure to install those as additional_dependencies in the
|
||||
# pre-commit hooks for pylint & mypy
|
||||
# Also update the readme accordingly
|
||||
#
|
||||
# When dependencies release new versions and tests succeed, we should try to expand the allowed
|
||||
# versions and only increase the lower bound if necessary
|
||||
#
|
||||
# When adding new groups, make sure to update `ext` and `all` accordingly
|
||||
|
||||
# Optional dependencies for production
|
||||
all = [
|
||||
"python-telegram-bot[ext,http2,passport,socks]",
|
||||
]
|
||||
callback-data = [
|
||||
# Cachetools doesn't have a strict stability policy. Let's be cautious for now.
|
||||
"cachetools>=5.3.3,<5.6.0",
|
||||
]
|
||||
ext = [
|
||||
"python-telegram-bot[callback-data,job-queue,rate-limiter,webhooks]",
|
||||
]
|
||||
http2 = [
|
||||
"httpx[http2]",
|
||||
]
|
||||
job-queue = [
|
||||
# APS doesn't have a strict stability policy. Let's be cautious for now.
|
||||
"APScheduler~=3.10.4",
|
||||
# pytz is required by APS and just needs the lower bound due to #2120
|
||||
"pytz>=2018.6",
|
||||
]
|
||||
passport = [
|
||||
"cryptography!=3.4,!=3.4.1,!=3.4.2,!=3.4.3,>=39.0.1",
|
||||
# cffi is a dependency of cryptography and added support for python 3.13 in 1.17.0rc1
|
||||
"cffi >= 1.17.0rc1; python_version > '3.12'"
|
||||
]
|
||||
rate-limiter = [
|
||||
"aiolimiter~=1.1.0",
|
||||
]
|
||||
socks = [
|
||||
"httpx[socks]",
|
||||
]
|
||||
webhooks = [
|
||||
# tornado is rather stable, but let's not allow the next major release without prior testing
|
||||
"tornado~=6.4",
|
||||
]
|
||||
|
||||
|
||||
# HATCH
|
||||
[tool.hatch.version]
|
||||
# dynamically evaluates the `__version__` variable in that file
|
||||
source = "code"
|
||||
path = "telegram/_version.py"
|
||||
search-paths = ["telegram"]
|
||||
|
||||
[tool.hatch.build]
|
||||
packages = ["telegram"]
|
||||
|
||||
# BLACK:
|
||||
[tool.black]
|
||||
line-length = 99
|
||||
target-version = ['py38', 'py39', 'py310', 'py311']
|
||||
|
||||
# ISORT:
|
||||
[tool.isort] # black config
|
||||
@@ -11,24 +120,29 @@ line_length = 99
|
||||
# RUFF:
|
||||
[tool.ruff]
|
||||
line-length = 99
|
||||
target-version = "py38"
|
||||
show-fixes = true
|
||||
|
||||
[tool.ruff.lint]
|
||||
preview = true
|
||||
explicit-preview-rules = true
|
||||
explicit-preview-rules = true # TODO: Drop this when RUF022 and RUF023 are out of preview
|
||||
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", "YTT", "DTZ", "ARG"]
|
||||
# Add "FURB" after it's out of preview
|
||||
"RUF023", "Q", "INP", "W", "YTT", "DTZ", "ARG", "T20", "FURB", "DOC", "TRY",
|
||||
"D100", "D101", "D102", "D103", "D300", "D418", "D419", "S"]
|
||||
# Add "A (flake8-builtins)" after we drop pylint
|
||||
|
||||
[tool.ruff.lint.per-file-ignores]
|
||||
"tests/*.py" = ["B018"]
|
||||
"tests/**.py" = ["RUF012", "ASYNC101", "DTZ", "ARG"]
|
||||
"docs/**.py" = ["INP001", "ARG"]
|
||||
"examples/**.py" = ["ARG"]
|
||||
"tests/**.py" = ["RUF012", "ASYNC230", "DTZ", "ARG", "T201", "ASYNC109", "D", "S", "TRY"]
|
||||
"telegram/**.py" = ["TRY003"]
|
||||
"telegram/ext/_applicationbuilder.py" = ["TRY004"]
|
||||
"telegram/ext/filters.py" = ["D102"]
|
||||
"docs/**.py" = ["INP001", "ARG", "D", "TRY003", "S"]
|
||||
"examples/**.py" = ["ARG", "D", "S105", "TRY003"]
|
||||
|
||||
[tool.ruff.lint.pydocstyle]
|
||||
convention = "google"
|
||||
|
||||
# PYLINT:
|
||||
[tool.pylint."messages control"]
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
-r requirements.txt
|
||||
-r requirements-dev.txt
|
||||
-r requirements-opts.txt
|
||||
-r docs/requirements-docs.txt
|
||||
@@ -0,0 +1,5 @@
|
||||
-e .[all]
|
||||
# needed for pre-commit hooks in the git commit command
|
||||
pre-commit
|
||||
-r requirements-unit-tests.txt
|
||||
-r docs/requirements-docs.txt
|
||||
@@ -1,11 +0,0 @@
|
||||
pre-commit # needed for pre-commit hooks in the git commit command
|
||||
|
||||
# For the test suite
|
||||
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
|
||||
|
||||
wheel # required for building the wheels for releases
|
||||
@@ -1,27 +0,0 @@
|
||||
# Format:
|
||||
# package_name==version # req-1, req-2, req-3!ext
|
||||
# `pip install ptb-raw[req-1/2]` will install `package_name`
|
||||
# `pip install ptb[req-1/2/3]` will also install `package_name`
|
||||
|
||||
# Make sure to install those as additional_dependencies in the
|
||||
# pre-commit hooks for pylint & mypy
|
||||
# Also update the readme accordingly
|
||||
|
||||
# When dependencies release new versions and tests succeed, we should try to expand the allowed
|
||||
# versions and only increase the lower bound if necessary
|
||||
|
||||
httpx[socks] # socks
|
||||
httpx[http2] # http2
|
||||
cryptography!=3.4,!=3.4.1,!=3.4.2,!=3.4.3,>=39.0.1 # passport
|
||||
aiolimiter~=1.1.0 # rate-limiter!ext
|
||||
|
||||
# tornado is rather stable, but let's not allow the next mayor release without prior testing
|
||||
tornado~=6.4 # webhooks!ext
|
||||
|
||||
# Cachetools and APS don't have a strict stability policy.
|
||||
# Let's be cautious for now.
|
||||
cachetools~=5.3.3 # callback-data!ext
|
||||
APScheduler~=3.10.4 # job-queue!ext
|
||||
|
||||
# pytz is required by APS and just needs the lower bound due to #2120
|
||||
pytz>=2018.6 # job-queue!ext
|
||||
@@ -0,0 +1,19 @@
|
||||
-e .
|
||||
|
||||
# required for building the wheels for releases
|
||||
build
|
||||
|
||||
# For the test suite
|
||||
pytest==8.3.2
|
||||
|
||||
# needed because pytest doesn't come with native support for coroutines as tests
|
||||
pytest-asyncio==0.21.2
|
||||
|
||||
# xdist runs tests in parallel
|
||||
pytest-xdist==3.6.1
|
||||
|
||||
# Used for flaky tests (flaky decorator)
|
||||
flaky>=3.8.1
|
||||
|
||||
# used in test_official for parsing tg docs
|
||||
beautifulsoup4
|
||||
@@ -1,10 +0,0 @@
|
||||
# Make sure to install those as additional_dependencies in the
|
||||
# pre-commit hooks for pylint & mypy
|
||||
# Also update the readme accordingly
|
||||
|
||||
# When dependencies release new versions and tests succeed, we should try to expand the allowed
|
||||
# versions and only increase the lower bound if necessary
|
||||
|
||||
# httpx has no stable release yet, but we've had no stability problems since v20.0a0 either
|
||||
# Since there have been requests to relax the bound a bit, we allow versions < 1.0.0
|
||||
httpx ~= 0.27
|
||||
@@ -1,8 +1,5 @@
|
||||
[metadata]
|
||||
license_files = LICENSE, LICENSE.dual, LICENSE.lesser
|
||||
|
||||
[flake8]
|
||||
max-line-length = 99
|
||||
ignore = W503, W605
|
||||
extend-ignore = E203, E704
|
||||
exclude = setup.py, setup_raw.py docs/source/conf.py
|
||||
exclude = docs/source/conf.py
|
||||
|
||||
@@ -1,131 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
"""The setup and build script for the python-telegram-bot library."""
|
||||
import subprocess
|
||||
import sys
|
||||
from collections import defaultdict
|
||||
from pathlib import Path
|
||||
from typing import Any, Dict, List, Tuple
|
||||
|
||||
from setuptools import find_packages, setup
|
||||
|
||||
|
||||
def get_requirements() -> List[str]:
|
||||
"""Build the requirements list for this project"""
|
||||
requirements_list = []
|
||||
|
||||
with Path("requirements.txt").open(encoding="utf-8") as reqs:
|
||||
for install in reqs:
|
||||
if install.startswith("#"):
|
||||
continue
|
||||
requirements_list.append(install.strip())
|
||||
|
||||
return requirements_list
|
||||
|
||||
|
||||
def get_packages_requirements(raw: bool = False) -> Tuple[List[str], List[str]]:
|
||||
"""Build the package & requirements list for this project"""
|
||||
reqs = get_requirements()
|
||||
|
||||
exclude = ["tests*", "docs*"]
|
||||
if raw:
|
||||
exclude.append("telegram.ext*")
|
||||
|
||||
packs = find_packages(exclude=exclude)
|
||||
|
||||
return packs, reqs
|
||||
|
||||
|
||||
def get_optional_requirements(raw: bool = False) -> Dict[str, List[str]]:
|
||||
"""Build the optional dependencies"""
|
||||
requirements = defaultdict(list)
|
||||
|
||||
with Path("requirements-opts.txt").open(encoding="utf-8") as reqs:
|
||||
for line in reqs:
|
||||
effective_line = line.strip()
|
||||
if not effective_line or effective_line.startswith("#"):
|
||||
continue
|
||||
dependency, names = effective_line.split("#")
|
||||
dependency = dependency.strip()
|
||||
for name in names.split(","):
|
||||
effective_name = name.strip()
|
||||
if effective_name.endswith("!ext"):
|
||||
if raw:
|
||||
continue
|
||||
effective_name = effective_name[:-4]
|
||||
requirements["ext"].append(dependency)
|
||||
requirements[effective_name].append(dependency)
|
||||
requirements["all"].append(dependency)
|
||||
|
||||
return requirements
|
||||
|
||||
|
||||
def get_setup_kwargs(raw: bool = False) -> Dict[str, Any]:
|
||||
"""Builds a dictionary of kwargs for the setup function"""
|
||||
packages, requirements = get_packages_requirements(raw=raw)
|
||||
|
||||
raw_ext = "-raw" if raw else ""
|
||||
readme = Path(f'README{"_RAW" if raw else ""}.rst')
|
||||
|
||||
version_file = Path("telegram/_version.py").read_text(encoding="utf-8")
|
||||
first_part = version_file.split("# SETUP.PY MARKER")[0]
|
||||
exec(first_part) # pylint: disable=exec-used
|
||||
|
||||
return {
|
||||
"script_name": f"setup{raw_ext}.py",
|
||||
"name": f"python-telegram-bot{raw_ext}",
|
||||
"version": locals()["__version__"],
|
||||
"author": "Leandro Toledo",
|
||||
"author_email": "devs@python-telegram-bot.org",
|
||||
"license": "LGPLv3",
|
||||
"url": "https://python-telegram-bot.org/",
|
||||
# Keywords supported by PyPI can be found at
|
||||
# https://github.com/pypa/warehouse/blob/aafc5185e57e67d43487ce4faa95913dd4573e14/
|
||||
# warehouse/templates/packaging/detail.html#L20-L58
|
||||
"project_urls": {
|
||||
"Documentation": "https://docs.python-telegram-bot.org",
|
||||
"Bug Tracker": "https://github.com/python-telegram-bot/python-telegram-bot/issues",
|
||||
"Source Code": "https://github.com/python-telegram-bot/python-telegram-bot",
|
||||
"News": "https://t.me/pythontelegrambotchannel",
|
||||
"Changelog": "https://docs.python-telegram-bot.org/en/stable/changelog.html",
|
||||
},
|
||||
"download_url": f"https://pypi.org/project/python-telegram-bot{raw_ext}/",
|
||||
"keywords": "python telegram bot api wrapper",
|
||||
"description": "We have made you a wrapper you can't refuse",
|
||||
"long_description": readme.read_text(encoding="utf-8"),
|
||||
"long_description_content_type": "text/x-rst",
|
||||
"packages": packages,
|
||||
"install_requires": requirements,
|
||||
"extras_require": get_optional_requirements(raw=raw),
|
||||
"include_package_data": True,
|
||||
"classifiers": [
|
||||
"Development Status :: 5 - Production/Stable",
|
||||
"Intended Audience :: Developers",
|
||||
"License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)",
|
||||
"Operating System :: OS Independent",
|
||||
"Topic :: Software Development :: Libraries :: Python Modules",
|
||||
"Topic :: Communications :: Chat",
|
||||
"Topic :: Internet",
|
||||
"Programming Language :: Python",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3.8",
|
||||
"Programming Language :: Python :: 3.9",
|
||||
"Programming Language :: Python :: 3.10",
|
||||
"Programming Language :: Python :: 3.11",
|
||||
"Programming Language :: Python :: 3.12",
|
||||
],
|
||||
"python_requires": ">=3.8",
|
||||
}
|
||||
|
||||
|
||||
def main() -> None:
|
||||
# If we're building, build ptb-raw as well
|
||||
if set(sys.argv[1:]) in [{"bdist_wheel"}, {"sdist"}, {"sdist", "bdist_wheel"}]:
|
||||
args = ["python", "setup_raw.py"]
|
||||
args.extend(sys.argv[1:])
|
||||
subprocess.run(args, check=True, capture_output=True)
|
||||
|
||||
setup(**get_setup_kwargs(raw=False))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,8 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
"""The setup and build script for the python-telegram-bot-raw library."""
|
||||
|
||||
from setuptools import setup
|
||||
|
||||
from setup import get_setup_kwargs
|
||||
|
||||
setup(**get_setup_kwargs(raw=True))
|
||||
+48
-31
@@ -142,6 +142,9 @@ __all__ = (
|
||||
"InputMediaPhoto",
|
||||
"InputMediaVideo",
|
||||
"InputMessageContent",
|
||||
"InputPaidMedia",
|
||||
"InputPaidMediaPhoto",
|
||||
"InputPaidMediaVideo",
|
||||
"InputPollOption",
|
||||
"InputSticker",
|
||||
"InputTextMessageContent",
|
||||
@@ -173,6 +176,11 @@ __all__ = (
|
||||
"MessageReactionCountUpdated",
|
||||
"MessageReactionUpdated",
|
||||
"OrderInfo",
|
||||
"PaidMedia",
|
||||
"PaidMediaInfo",
|
||||
"PaidMediaPhoto",
|
||||
"PaidMediaPreview",
|
||||
"PaidMediaVideo",
|
||||
"PassportData",
|
||||
"PassportElementError",
|
||||
"PassportElementErrorDataField",
|
||||
@@ -196,10 +204,16 @@ __all__ = (
|
||||
"ReactionType",
|
||||
"ReactionTypeCustomEmoji",
|
||||
"ReactionTypeEmoji",
|
||||
"ReactionTypePaid",
|
||||
"RefundedPayment",
|
||||
"ReplyKeyboardMarkup",
|
||||
"ReplyKeyboardRemove",
|
||||
"ReplyParameters",
|
||||
"ResidentialAddress",
|
||||
"RevenueWithdrawalState",
|
||||
"RevenueWithdrawalStateFailed",
|
||||
"RevenueWithdrawalStatePending",
|
||||
"RevenueWithdrawalStateSucceeded",
|
||||
"SecureData",
|
||||
"SecureValue",
|
||||
"SentWebAppMessage",
|
||||
@@ -207,6 +221,8 @@ __all__ = (
|
||||
"ShippingAddress",
|
||||
"ShippingOption",
|
||||
"ShippingQuery",
|
||||
"StarTransaction",
|
||||
"StarTransactions",
|
||||
"Sticker",
|
||||
"StickerSet",
|
||||
"Story",
|
||||
@@ -214,6 +230,11 @@ __all__ = (
|
||||
"SwitchInlineQueryChosenChat",
|
||||
"TelegramObject",
|
||||
"TextQuote",
|
||||
"TransactionPartner",
|
||||
"TransactionPartnerFragment",
|
||||
"TransactionPartnerOther",
|
||||
"TransactionPartnerTelegramAds",
|
||||
"TransactionPartnerUser",
|
||||
"Update",
|
||||
"User",
|
||||
"UserChatBoosts",
|
||||
@@ -242,8 +263,6 @@ __all__ = (
|
||||
"warnings",
|
||||
)
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from . import _version, constants, error, helpers, request, warnings
|
||||
from ._birthdate import Birthdate
|
||||
from ._bot import Bot
|
||||
@@ -325,6 +344,9 @@ from ._files.inputmedia import (
|
||||
InputMediaDocument,
|
||||
InputMediaPhoto,
|
||||
InputMediaVideo,
|
||||
InputPaidMedia,
|
||||
InputPaidMediaPhoto,
|
||||
InputPaidMediaVideo,
|
||||
)
|
||||
from ._files.inputsticker import InputSticker
|
||||
from ._files.location import Location
|
||||
@@ -397,6 +419,7 @@ from ._messageorigin import (
|
||||
MessageOriginUser,
|
||||
)
|
||||
from ._messagereactionupdated import MessageReactionCountUpdated, MessageReactionUpdated
|
||||
from ._paidmedia import PaidMedia, PaidMediaInfo, PaidMediaPhoto, PaidMediaPreview, PaidMediaVideo
|
||||
from ._passport.credentials import (
|
||||
Credentials,
|
||||
DataCredentials,
|
||||
@@ -425,13 +448,33 @@ from ._payment.invoice import Invoice
|
||||
from ._payment.labeledprice import LabeledPrice
|
||||
from ._payment.orderinfo import OrderInfo
|
||||
from ._payment.precheckoutquery import PreCheckoutQuery
|
||||
from ._payment.refundedpayment import RefundedPayment
|
||||
from ._payment.shippingaddress import ShippingAddress
|
||||
from ._payment.shippingoption import ShippingOption
|
||||
from ._payment.shippingquery import ShippingQuery
|
||||
from ._payment.stars import (
|
||||
RevenueWithdrawalState,
|
||||
RevenueWithdrawalStateFailed,
|
||||
RevenueWithdrawalStatePending,
|
||||
RevenueWithdrawalStateSucceeded,
|
||||
StarTransaction,
|
||||
StarTransactions,
|
||||
TransactionPartner,
|
||||
TransactionPartnerFragment,
|
||||
TransactionPartnerOther,
|
||||
TransactionPartnerTelegramAds,
|
||||
TransactionPartnerUser,
|
||||
)
|
||||
from ._payment.successfulpayment import SuccessfulPayment
|
||||
from ._poll import InputPollOption, Poll, PollAnswer, PollOption
|
||||
from ._proximityalerttriggered import ProximityAlertTriggered
|
||||
from ._reaction import ReactionCount, ReactionType, ReactionTypeCustomEmoji, ReactionTypeEmoji
|
||||
from ._reaction import (
|
||||
ReactionCount,
|
||||
ReactionType,
|
||||
ReactionTypeCustomEmoji,
|
||||
ReactionTypeEmoji,
|
||||
ReactionTypePaid,
|
||||
)
|
||||
from ._reply import ExternalReplyInfo, ReplyParameters, TextQuote
|
||||
from ._replykeyboardmarkup import ReplyKeyboardMarkup
|
||||
from ._replykeyboardremove import ReplyKeyboardRemove
|
||||
@@ -443,7 +486,6 @@ 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,
|
||||
@@ -472,33 +514,8 @@ __version_info__: _version.Version = _version.__version_info__
|
||||
#:
|
||||
#: .. versionchanged:: 20.0
|
||||
#: This constant was previously named ``bot_api_version``.
|
||||
__bot_api_version__: str = _version.__bot_api_version__
|
||||
__bot_api_version__: str = constants.BOT_API_VERSION
|
||||
#: :class:`typing.NamedTuple`: Shortcut for :const:`telegram.constants.BOT_API_VERSION_INFO`.
|
||||
#:
|
||||
#: .. 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,
|
||||
)
|
||||
__bot_api_version_info__: constants._BotAPIVersion = constants.BOT_API_VERSION_INFO
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
# pylint: disable=missing-module-docstring
|
||||
# ruff: noqa: T201, D100, S603, S607
|
||||
import subprocess
|
||||
import sys
|
||||
from typing import Optional
|
||||
|
||||
+406
-81
@@ -18,6 +18,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 Bot."""
|
||||
|
||||
import asyncio
|
||||
import contextlib
|
||||
import copy
|
||||
@@ -70,7 +71,7 @@ from telegram._files.chatphoto import ChatPhoto
|
||||
from telegram._files.contact import Contact
|
||||
from telegram._files.document import Document
|
||||
from telegram._files.file import File
|
||||
from telegram._files.inputmedia import InputMedia
|
||||
from telegram._files.inputmedia import InputMedia, InputPaidMedia
|
||||
from telegram._files.location import Location
|
||||
from telegram._files.photosize import PhotoSize
|
||||
from telegram._files.sticker import MaskPosition, Sticker, StickerSet
|
||||
@@ -84,6 +85,7 @@ from telegram._inline.inlinequeryresultsbutton import InlineQueryResultsButton
|
||||
from telegram._menubutton import MenuButton
|
||||
from telegram._message import Message
|
||||
from telegram._messageid import MessageId
|
||||
from telegram._payment.stars import StarTransactions
|
||||
from telegram._poll import InputPollOption, Poll
|
||||
from telegram._reaction import ReactionType, ReactionTypeCustomEmoji, ReactionTypeEmoji
|
||||
from telegram._reply import ReplyParameters
|
||||
@@ -323,10 +325,10 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
"""
|
||||
try:
|
||||
await self.initialize()
|
||||
return self
|
||||
except Exception as exc:
|
||||
except Exception:
|
||||
await self.shutdown()
|
||||
raise exc
|
||||
raise
|
||||
return self
|
||||
|
||||
async def __aexit__(
|
||||
self,
|
||||
@@ -577,13 +579,16 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
with new._unfrozen():
|
||||
new.parse_mode = DefaultValue.get_value(new.parse_mode)
|
||||
data[key] = new
|
||||
elif key == "media" and isinstance(val, Sequence):
|
||||
elif (
|
||||
key == "media"
|
||||
and isinstance(val, Sequence)
|
||||
and not isinstance(val[0], InputPaidMedia)
|
||||
):
|
||||
# Copy objects as not to edit them in-place
|
||||
copy_list = [copy.copy(media) for media in val]
|
||||
for media in copy_list:
|
||||
with media._unfrozen():
|
||||
media.parse_mode = DefaultValue.get_value(media.parse_mode)
|
||||
|
||||
data[key] = copy_list
|
||||
# 2)
|
||||
else:
|
||||
@@ -1301,8 +1306,8 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
|
||||
Args:
|
||||
chat_id (:obj:`int` | :obj:`str`): |chat_id_channel|
|
||||
photo (:obj:`str` | :term:`file object` | :obj:`bytes` | :class:`pathlib.Path` | \
|
||||
:class:`telegram.PhotoSize`): Photo to send.
|
||||
photo (:obj:`str` | :term:`file object` | :class:`~telegram.InputFile` | :obj:`bytes` \
|
||||
| :class:`pathlib.Path` | :class:`telegram.PhotoSize`): Photo to send.
|
||||
|fileinput|
|
||||
Lastly you can pass an existing :class:`telegram.PhotoSize` object to send.
|
||||
|
||||
@@ -1461,9 +1466,9 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
|
||||
Args:
|
||||
chat_id (:obj:`int` | :obj:`str`): |chat_id_channel|
|
||||
audio (:obj:`str` | :term:`file object` | :obj:`bytes` | :class:`pathlib.Path` | \
|
||||
:class:`telegram.Audio`): Audio file to send.
|
||||
|fileinput|
|
||||
audio (:obj:`str` | :term:`file object` | :class:`~telegram.InputFile` | \
|
||||
:obj:`bytes` | :class:`pathlib.Path` | :class:`telegram.Audio`): Audio file to
|
||||
send. |fileinput|
|
||||
Lastly you can pass an existing :class:`telegram.Audio` object to send.
|
||||
|
||||
.. versionchanged:: 13.2
|
||||
@@ -1613,8 +1618,8 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
|
||||
Args:
|
||||
chat_id (:obj:`int` | :obj:`str`): |chat_id_channel|
|
||||
document (:obj:`str` | :term:`file object` | :obj:`bytes` | :class:`pathlib.Path` | \
|
||||
:class:`telegram.Document`): File to send.
|
||||
document (:obj:`str` | :term:`file object` | :class:`~telegram.InputFile` | \
|
||||
:obj:`bytes` | :class:`pathlib.Path` | :class:`telegram.Document`): File to send.
|
||||
|fileinput|
|
||||
Lastly you can pass an existing :class:`telegram.Document` object to send.
|
||||
|
||||
@@ -1751,8 +1756,8 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
|
||||
Args:
|
||||
chat_id (:obj:`int` | :obj:`str`): |chat_id_channel|
|
||||
sticker (:obj:`str` | :term:`file object` | :obj:`bytes` | :class:`pathlib.Path` | \
|
||||
:class:`telegram.Sticker`): Sticker to send.
|
||||
sticker (:obj:`str` | :term:`file object` | :class:`~telegram.InputFile` | \
|
||||
:obj:`bytes` | :class:`pathlib.Path` | :class:`telegram.Sticker`): Sticker to send.
|
||||
|fileinput| Video stickers can only be sent by a ``file_id``. Video and animated
|
||||
stickers can't be sent via an HTTP URL.
|
||||
|
||||
@@ -1891,8 +1896,8 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
|
||||
Args:
|
||||
chat_id (:obj:`int` | :obj:`str`): |chat_id_channel|
|
||||
video (:obj:`str` | :term:`file object` | :obj:`bytes` | :class:`pathlib.Path` | \
|
||||
:class:`telegram.Video`): Video file to send.
|
||||
video (:obj:`str` | :term:`file object` | :class:`~telegram.InputFile` | :obj:`bytes` \
|
||||
| :class:`pathlib.Path` | :class:`telegram.Video`): Video file to send.
|
||||
|fileinput|
|
||||
Lastly you can pass an existing :class:`telegram.Video` object to send.
|
||||
|
||||
@@ -2055,8 +2060,9 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
|
||||
Args:
|
||||
chat_id (:obj:`int` | :obj:`str`): |chat_id_channel|
|
||||
video_note (:obj:`str` | :term:`file object` | :obj:`bytes` | :class:`pathlib.Path` | \
|
||||
:class:`telegram.VideoNote`): Video note to send.
|
||||
video_note (:obj:`str` | :term:`file object` | :class:`~telegram.InputFile` | \
|
||||
:obj:`bytes` | :class:`pathlib.Path` | :class:`telegram.VideoNote`): Video note
|
||||
to send.
|
||||
Pass a file_id as String to send a video note that exists on the Telegram
|
||||
servers (recommended) or upload a new video using multipart/form-data.
|
||||
|uploadinput|
|
||||
@@ -2205,9 +2211,9 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
|
||||
Args:
|
||||
chat_id (:obj:`int` | :obj:`str`): |chat_id_channel|
|
||||
animation (:obj:`str` | :term:`file object` | :obj:`bytes` | :class:`pathlib.Path` | \
|
||||
:class:`telegram.Animation`): Animation to send.
|
||||
|fileinput|
|
||||
animation (:obj:`str` | :term:`file object` | :class:`~telegram.InputFile` | \
|
||||
:obj:`bytes` | :class:`pathlib.Path` | :class:`telegram.Animation`): Animation to
|
||||
send. |fileinput|
|
||||
Lastly you can pass an existing :class:`telegram.Animation` object to send.
|
||||
|
||||
.. versionchanged:: 13.2
|
||||
@@ -2367,8 +2373,8 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
|
||||
Args:
|
||||
chat_id (:obj:`int` | :obj:`str`): |chat_id_channel|
|
||||
voice (:obj:`str` | :term:`file object` | :obj:`bytes` | :class:`pathlib.Path` | \
|
||||
:class:`telegram.Voice`): Voice file to send.
|
||||
voice (:obj:`str` | :term:`file object` | :class:`~telegram.InputFile` | :obj:`bytes` \
|
||||
| :class:`pathlib.Path` | :class:`telegram.Voice`): Voice file to send.
|
||||
|fileinput|
|
||||
Lastly you can pass an existing :class:`telegram.Voice` object to send.
|
||||
|
||||
@@ -2802,6 +2808,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
heading: Optional[int] = None,
|
||||
proximity_alert_radius: Optional[int] = None,
|
||||
live_period: Optional[int] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
*,
|
||||
location: Optional[Location] = None,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
@@ -2849,6 +2856,9 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
remains unchanged
|
||||
|
||||
.. versionadded:: 21.2.
|
||||
business_connection_id (:obj:`str`, optional): |business_id_str_edit|
|
||||
|
||||
.. versionadded:: 21.4
|
||||
|
||||
Keyword Args:
|
||||
location (:class:`telegram.Location`, optional): The location to send.
|
||||
@@ -2888,6 +2898,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
"editMessageLiveLocation",
|
||||
data,
|
||||
reply_markup=reply_markup,
|
||||
business_connection_id=business_connection_id,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
@@ -2901,6 +2912,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
message_id: Optional[int] = None,
|
||||
inline_message_id: Optional[str] = None,
|
||||
reply_markup: Optional["InlineKeyboardMarkup"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
@@ -2920,6 +2932,9 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
:paramref:`message_id` are not specified. Identifier of the inline message.
|
||||
reply_markup (:class:`telegram.InlineKeyboardMarkup`, optional): An object for a new
|
||||
inline keyboard.
|
||||
business_connection_id (:obj:`str`, optional): |business_id_str_edit|
|
||||
|
||||
.. versionadded:: 21.4
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, if edited message is not an inline message, the
|
||||
@@ -2935,6 +2950,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
"stopMessageLiveLocation",
|
||||
data,
|
||||
reply_markup=reply_markup,
|
||||
business_connection_id=business_connection_id,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
@@ -3945,6 +3961,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
reply_markup: Optional["InlineKeyboardMarkup"] = None,
|
||||
entities: Optional[Sequence["MessageEntity"]] = None,
|
||||
link_preview_options: ODVInput["LinkPreviewOptions"] = DEFAULT_NONE,
|
||||
business_connection_id: Optional[str] = None,
|
||||
*,
|
||||
disable_web_page_preview: Optional[bool] = None,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
@@ -3957,7 +3974,8 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
Use this method to edit text and game messages.
|
||||
|
||||
Note:
|
||||
|editreplymarkup|.
|
||||
* |editreplymarkup|
|
||||
* |bcid_edit_time|
|
||||
|
||||
.. seealso:: :attr:`telegram.Game.text`
|
||||
|
||||
@@ -3988,6 +4006,9 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
|
||||
reply_markup (:class:`telegram.InlineKeyboardMarkup`, optional): An object for an
|
||||
inline keyboard.
|
||||
business_connection_id (:obj:`str`, optional): |business_id_str_edit|
|
||||
|
||||
.. versionadded:: 21.4
|
||||
|
||||
Keyword Args:
|
||||
disable_web_page_preview (:obj:`bool`, optional): Disables link previews for links in
|
||||
@@ -4029,6 +4050,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
reply_markup=reply_markup,
|
||||
parse_mode=parse_mode,
|
||||
link_preview_options=link_preview_options,
|
||||
business_connection_id=business_connection_id,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
@@ -4046,6 +4068,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Optional[Sequence["MessageEntity"]] = None,
|
||||
show_caption_above_media: Optional[bool] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
@@ -4057,7 +4080,8 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
Use this method to edit captions of messages.
|
||||
|
||||
Note:
|
||||
|editreplymarkup|
|
||||
* |editreplymarkup|
|
||||
* |bcid_edit_time|
|
||||
|
||||
Args:
|
||||
chat_id (:obj:`int` | :obj:`str`, optional): Required if inline_message_id is not
|
||||
@@ -4080,6 +4104,9 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
show_caption_above_media (:obj:`bool`, optional): Pass |show_cap_above_med|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
business_connection_id (:obj:`str`, optional): |business_id_str_edit|
|
||||
|
||||
.. versionadded:: 21.4
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, if edited message is not an inline message, the
|
||||
@@ -4103,6 +4130,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
caption=caption,
|
||||
parse_mode=parse_mode,
|
||||
caption_entities=caption_entities,
|
||||
business_connection_id=business_connection_id,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
@@ -4117,6 +4145,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
message_id: Optional[int] = None,
|
||||
inline_message_id: Optional[str] = None,
|
||||
reply_markup: Optional["InlineKeyboardMarkup"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
@@ -4132,7 +4161,8 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
:attr:`~telegram.File.file_id` or specify a URL.
|
||||
|
||||
Note:
|
||||
|editreplymarkup|
|
||||
* |editreplymarkup|
|
||||
* |bcid_edit_time|
|
||||
|
||||
.. seealso:: :wiki:`Working with Files and Media <Working-with-Files-and-Media>`
|
||||
|
||||
@@ -4147,6 +4177,9 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
specified. Identifier of the inline message.
|
||||
reply_markup (:class:`telegram.InlineKeyboardMarkup`, optional): An object for an
|
||||
inline keyboard.
|
||||
business_connection_id (:obj:`str`, optional): |business_id_str_edit|
|
||||
|
||||
.. versionadded:: 21.4
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, if edited message is not an inline message, the
|
||||
@@ -4166,6 +4199,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
"editMessageMedia",
|
||||
data,
|
||||
reply_markup=reply_markup,
|
||||
business_connection_id=business_connection_id,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
@@ -4179,6 +4213,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
message_id: Optional[int] = None,
|
||||
inline_message_id: Optional[str] = None,
|
||||
reply_markup: Optional["InlineKeyboardMarkup"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
@@ -4191,7 +4226,8 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
(for inline bots).
|
||||
|
||||
Note:
|
||||
|editreplymarkup|
|
||||
* |editreplymarkup|
|
||||
* |bcid_edit_time|
|
||||
|
||||
Args:
|
||||
chat_id (:obj:`int` | :obj:`str`, optional): Required if inline_message_id is not
|
||||
@@ -4202,6 +4238,9 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
specified. Identifier of the inline message.
|
||||
reply_markup (:class:`telegram.InlineKeyboardMarkup`, optional): An object for an
|
||||
inline keyboard.
|
||||
business_connection_id (:obj:`str`, optional): |business_id_str_edit|
|
||||
|
||||
.. versionadded:: 21.4
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, if edited message is not an inline message, the
|
||||
@@ -4221,6 +4260,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
"editMessageReplyMarkup",
|
||||
data,
|
||||
reply_markup=reply_markup,
|
||||
business_connection_id=business_connection_id,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
@@ -4232,7 +4272,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
self,
|
||||
offset: Optional[int] = None,
|
||||
limit: Optional[int] = None,
|
||||
timeout: Optional[int] = None,
|
||||
timeout: Optional[int] = None, # noqa: ASYNC109
|
||||
allowed_updates: Optional[Sequence[str]] = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
@@ -4339,7 +4379,16 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
else:
|
||||
self._LOGGER.debug("No new updates found.")
|
||||
|
||||
return Update.de_list(result, self)
|
||||
try:
|
||||
return Update.de_list(result, self)
|
||||
except Exception as exc:
|
||||
# This logging is in place mostly b/c we can't access the raw json data in Updater,
|
||||
# where the exception is caught and logged again. Still, it might also be beneficial
|
||||
# for custom usages of `get_updates`.
|
||||
self._LOGGER.critical(
|
||||
"Error while parsing updates! Received data was %r", result, exc_info=exc
|
||||
)
|
||||
raise
|
||||
|
||||
async def set_webhook(
|
||||
self,
|
||||
@@ -4379,18 +4428,6 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
If you're having any trouble setting up webhooks, please check out this `guide to
|
||||
Webhooks`_.
|
||||
|
||||
Note:
|
||||
1. You will not be able to receive updates using :meth:`get_updates` for long as an
|
||||
outgoing webhook is set up.
|
||||
2. To use a self-signed certificate, you need to upload your public key certificate
|
||||
using certificate parameter. Please upload as InputFile, sending a String will not
|
||||
work.
|
||||
3. Ports currently supported for Webhooks:
|
||||
:attr:`telegram.constants.SUPPORTED_WEBHOOK_PORTS`.
|
||||
|
||||
If you're having any trouble setting up webhooks, please check out this `guide to
|
||||
Webhooks`_.
|
||||
|
||||
.. seealso:: :meth:`telegram.ext.Application.run_webhook`,
|
||||
:meth:`telegram.ext.Updater.start_webhook`
|
||||
|
||||
@@ -4971,7 +5008,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
payload (:obj:`str`): Bot-defined invoice payload.
|
||||
:tg-const:`telegram.Invoice.MIN_PAYLOAD_LENGTH`-
|
||||
:tg-const:`telegram.Invoice.MAX_PAYLOAD_LENGTH` bytes. This will not be
|
||||
displayed to the user, use for your internal processes.
|
||||
displayed to the user, use it for your internal processes.
|
||||
provider_token (:obj:`str`): Payments provider token, obtained via
|
||||
`@BotFather <https://t.me/BotFather>`_. Pass an empty string for payments in
|
||||
|tg_stars|.
|
||||
@@ -4990,15 +5027,16 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceargs|
|
||||
max_tip_amount (:obj:`int`, optional): The maximum accepted amount for tips in the
|
||||
*smallest* units of the currency (integer, **not** float/double). For example, for
|
||||
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``. Not supported for payment in |tg_stars|
|
||||
*smallest units* of the currency (integer, **not** float/double). For example, for
|
||||
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``. Not supported for payment in |tg_stars|.
|
||||
|
||||
.. versionadded:: 13.5
|
||||
suggested_tip_amounts (Sequence[:obj:`int`], optional): An array of
|
||||
suggested amounts of tips in the *smallest* units of the currency (integer, **not**
|
||||
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
|
||||
amounts can be specified. The suggested tip amounts must be positive, passed in a
|
||||
strictly increased order and must not exceed :paramref:`max_tip_amount`.
|
||||
@@ -5736,10 +5774,10 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
|
||||
Args:
|
||||
chat_id (:obj:`int` | :obj:`str`): |chat_id_channel|
|
||||
invite_link (:obj:`str` | :obj:`telegram.ChatInviteLink`): The invite link to edit.
|
||||
invite_link (:obj:`str` | :class:`telegram.ChatInviteLink`): The invite link to edit.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
Now also accepts :obj:`telegram.ChatInviteLink` instances.
|
||||
Now also accepts :class:`telegram.ChatInviteLink` instances.
|
||||
expire_date (:obj:`int` | :obj:`datetime.datetime`, optional): Date when the link will
|
||||
expire.
|
||||
For timezone naive :obj:`datetime.datetime` objects, the default timezone of the
|
||||
@@ -5808,10 +5846,10 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
|
||||
Args:
|
||||
chat_id (:obj:`int` | :obj:`str`): |chat_id_channel|
|
||||
invite_link (:obj:`str` | :obj:`telegram.ChatInviteLink`): The invite link to revoke.
|
||||
invite_link (:obj:`str` | :class:`telegram.ChatInviteLink`): The invite link to revoke.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
Now also accepts :obj:`telegram.ChatInviteLink` instances.
|
||||
Now also accepts :class:`telegram.ChatInviteLink` instances.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.ChatInviteLink`
|
||||
@@ -6083,6 +6121,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
chat_id: Union[str, int],
|
||||
message_id: int,
|
||||
disable_notification: ODVInput[bool] = DEFAULT_NONE,
|
||||
business_connection_id: Optional[str] = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
@@ -6103,6 +6142,10 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
disable_notification (:obj:`bool`, optional): Pass :obj:`True`, if it is not necessary
|
||||
to send a notification to all chat members about the new pinned message.
|
||||
Notifications are always disabled in channels and private chats.
|
||||
business_connection_id (:obj:`str`, optional): Unique identifier of the business
|
||||
connection on behalf of which the message will be pinned.
|
||||
|
||||
.. versionadded:: 21.5
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
@@ -6115,6 +6158,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
"chat_id": chat_id,
|
||||
"message_id": message_id,
|
||||
"disable_notification": disable_notification,
|
||||
"business_connection_id": business_connection_id,
|
||||
}
|
||||
|
||||
return await self._post(
|
||||
@@ -6131,6 +6175,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
self,
|
||||
chat_id: Union[str, int],
|
||||
message_id: Optional[int] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
@@ -6147,8 +6192,13 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
|
||||
Args:
|
||||
chat_id (:obj:`int` | :obj:`str`): |chat_id_channel|
|
||||
message_id (:obj:`int`, optional): Identifier of a message to unpin. If not specified,
|
||||
message_id (:obj:`int`, optional): Identifier of the message to unpin. Required if
|
||||
:paramref:`business_connection_id` is specified. If not specified,
|
||||
the most recent pinned message (by sending date) will be unpinned.
|
||||
business_connection_id (:obj:`str`, optional): Unique identifier of the business
|
||||
connection on behalf of which the message will be unpinned.
|
||||
|
||||
.. versionadded:: 21.5
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
@@ -6157,7 +6207,11 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||
:class:`telegram.error.TelegramError`
|
||||
|
||||
"""
|
||||
data: JSONDict = {"chat_id": chat_id, "message_id": message_id}
|
||||
data: JSONDict = {
|
||||
"chat_id": chat_id,
|
||||
"message_id": message_id,
|
||||
"business_connection_id": business_connection_id,
|
||||
}
|
||||
|
||||
return await self._post(
|
||||
"unpinChatMessage",
|
||||
@@ -6306,8 +6360,9 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
|
||||
Args:
|
||||
user_id (:obj:`int`): User identifier of sticker file owner.
|
||||
sticker (:obj:`str` | :term:`file object` | :obj:`bytes` | :class:`pathlib.Path`):
|
||||
A file with the sticker in the ``".WEBP"``, ``".PNG"``, ``".TGS"`` or ``".WEBM"``
|
||||
sticker (:obj:`str` | :term:`file object` | :class:`~telegram.InputFile` | \
|
||||
:obj:`bytes` | :class:`pathlib.Path`): A file with the sticker in the
|
||||
``".WEBP"``, ``".PNG"``, ``".TGS"`` or ``".WEBM"``
|
||||
format. See `here <https://core.telegram.org/stickers>`_ for technical requirements
|
||||
. |uploadinput|
|
||||
|
||||
@@ -6631,8 +6686,9 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
|
||||
thumbnail (:obj:`str` | :term:`file object` | :obj:`bytes` | :class:`pathlib.Path`, \
|
||||
optional): A **.WEBP** or **.PNG** image with the thumbnail, must
|
||||
thumbnail (:obj:`str` | :term:`file object` | :class:`~telegram.InputFile` | \
|
||||
:obj:`bytes` | :class:`pathlib.Path`, optional): A **.WEBP** or **.PNG** image
|
||||
with the thumbnail, must
|
||||
be up to :tg-const:`telegram.constants.StickerSetLimit.MAX_STATIC_THUMBNAIL_SIZE`
|
||||
kilobytes in size and have width and height of exactly
|
||||
:tg-const:`telegram.constants.StickerSetLimit.STATIC_THUMB_DIMENSIONS` px, or a
|
||||
@@ -7119,6 +7175,7 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
chat_id: Union[int, str],
|
||||
message_id: int,
|
||||
reply_markup: Optional["InlineKeyboardMarkup"] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
@@ -7134,6 +7191,9 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
message_id (:obj:`int`): Identifier of the original message with the poll.
|
||||
reply_markup (:class:`telegram.InlineKeyboardMarkup`, optional): An object for a new
|
||||
message inline keyboard.
|
||||
business_connection_id (:obj:`str`, optional): |business_id_str_edit|
|
||||
|
||||
.. versionadded:: 21.4
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Poll`: On success, the stopped Poll is returned.
|
||||
@@ -7146,6 +7206,7 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
"chat_id": chat_id,
|
||||
"message_id": message_id,
|
||||
"reply_markup": reply_markup,
|
||||
"business_connection_id": business_connection_id,
|
||||
}
|
||||
|
||||
result = await self._post(
|
||||
@@ -7330,8 +7391,9 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
.. versionadded:: 20.0
|
||||
|
||||
Args:
|
||||
rights (:obj:`telegram.ChatAdministratorRights`, optional): A
|
||||
:obj:`telegram.ChatAdministratorRights` object describing new default administrator
|
||||
rights (:class:`telegram.ChatAdministratorRights`, optional): A
|
||||
:class:`telegram.ChatAdministratorRights` object describing new default
|
||||
administrator
|
||||
rights. If not specified, the default administrator rights will be cleared.
|
||||
for_channels (:obj:`bool`, optional): Pass :obj:`True` to change the default
|
||||
administrator rights of the bot in channels. Otherwise, the default administrator
|
||||
@@ -7341,7 +7403,7 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
:obj:`bool`: Returns :obj:`True` on success.
|
||||
|
||||
Raises:
|
||||
:obj:`telegram.error.TelegramError`
|
||||
:exc:`telegram.error.TelegramError`
|
||||
"""
|
||||
data: JSONDict = {"rights": rights, "for_channels": for_channels}
|
||||
|
||||
@@ -7605,7 +7667,8 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
pool_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
) -> MessageId:
|
||||
"""Use this method to copy messages of any kind. Service messages and invoice messages
|
||||
"""Use this method to copy messages of any kind. Service messages, paid media messages,
|
||||
giveaway messages, giveaway winners messages, and invoice messages
|
||||
can't be copied. The method is analogous to the method :meth:`forward_message`, but the
|
||||
copied message doesn't have a link to the original message.
|
||||
|
||||
@@ -7731,11 +7794,12 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
) -> Tuple["MessageId", ...]:
|
||||
"""
|
||||
Use this method to copy messages of any kind. If some of the specified messages can't be
|
||||
found or copied, they are skipped. Service messages, giveaway messages, giveaway winners
|
||||
messages, and invoice messages can't be copied. A quiz poll can be copied only if the value
|
||||
of the field correct_option_id is known to the bot. The method is analogous to the method
|
||||
:meth:`forward_messages`, but the copied messages don't have a link to the original
|
||||
message. Album grouping is kept for copied messages.
|
||||
found or copied, they are skipped. Service messages, paid media messages, giveaway
|
||||
messages, giveaway winners messages, and invoice messages can't be copied. A quiz poll can
|
||||
be copied only if the value
|
||||
of the field :attr:`telegram.Poll.correct_option_id` is known to the bot. The method is
|
||||
analogous to the method :meth:`forward_messages`, but the copied messages don't have a
|
||||
link to the original message. Album grouping is kept for copied messages.
|
||||
|
||||
.. versionadded:: 20.8
|
||||
|
||||
@@ -7905,7 +7969,7 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
payload (:obj:`str`): Bot-defined invoice payload.
|
||||
:tg-const:`telegram.Invoice.MIN_PAYLOAD_LENGTH`-
|
||||
:tg-const:`telegram.Invoice.MAX_PAYLOAD_LENGTH` bytes. This will not be
|
||||
displayed to the user, use for your internal processes.
|
||||
displayed to the user, use it for your internal processes.
|
||||
provider_token (:obj:`str`): Payments provider token, obtained via
|
||||
`@BotFather <https://t.me/BotFather>`_. Pass an empty string for payments in
|
||||
|tg_stars|.
|
||||
@@ -7924,14 +7988,14 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceargs|
|
||||
max_tip_amount (:obj:`int`, optional): The maximum accepted amount for tips in the
|
||||
*smallest* units of the currency (integer, **not** float/double). For example, for
|
||||
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``. Not supported for payments in
|
||||
|tg_stars|.
|
||||
*smallest units* of the currency (integer, **not** float/double). For example, for
|
||||
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``. 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**
|
||||
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
|
||||
amounts can be specified. The suggested tip amounts must be positive, passed in a
|
||||
strictly increased order and must not exceed :paramref:`max_tip_amount`.
|
||||
@@ -8105,7 +8169,7 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
) -> bool:
|
||||
"""
|
||||
Use this method to edit name and icon of a topic in a forum supergroup chat. The bot must
|
||||
be an administrator in the chat for this to work and must have
|
||||
be an administrator in the chat for this to work and must have the
|
||||
:paramref:`~telegram.ChatAdministratorRights.can_manage_topics` administrator rights,
|
||||
unless it is the creator of the topic.
|
||||
|
||||
@@ -8373,7 +8437,7 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
) -> bool:
|
||||
"""
|
||||
Use this method to edit the name of the 'General' topic in a forum supergroup chat. The bot
|
||||
must be an administrator in the chat for this to work and must have
|
||||
must be an administrator in the chat for this to work and must have the
|
||||
:attr:`~telegram.ChatAdministratorRights.can_manage_topics` administrator rights.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
@@ -8872,7 +8936,7 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
"""
|
||||
Use this method to change the chosen reactions on a message. Service messages can't be
|
||||
reacted to. Automatically forwarded messages from a channel to its discussion group have
|
||||
the same available reactions as messages in the channel.
|
||||
the same available reactions as messages in the channel. Bots can't use paid reactions.
|
||||
|
||||
.. versionadded:: 20.8
|
||||
|
||||
@@ -8885,7 +8949,8 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
:class:`telegram.ReactionType` | :obj:`str`, optional): A list of reaction
|
||||
types to set on the message. Currently, as non-premium users, bots can set up to
|
||||
one reaction per message. A custom emoji reaction can be used if it is either
|
||||
already present on the message or explicitly allowed by chat administrators.
|
||||
already present on the message or explicitly allowed by chat administrators. Paid
|
||||
reactions can't be used by bots.
|
||||
|
||||
Tip:
|
||||
Passed :obj:`str` values will be converted to either
|
||||
@@ -9002,7 +9067,7 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
user_id (:obj:`int`): User identifier of the sticker set owner.
|
||||
name (:obj:`str`): Sticker set name.
|
||||
old_sticker (:obj:`str`): File identifier of the replaced sticker.
|
||||
sticker (:obj:`telegram.InputSticker`): An object with information about the added
|
||||
sticker (:class:`telegram.InputSticker`): An object with information about the added
|
||||
sticker. If exactly the same sticker had already been added to the set, then the
|
||||
set remains unchanged.
|
||||
|
||||
@@ -9070,6 +9135,258 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
async def get_star_transactions(
|
||||
self,
|
||||
offset: Optional[int] = None,
|
||||
limit: Optional[int] = None,
|
||||
*,
|
||||
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,
|
||||
) -> StarTransactions:
|
||||
"""Returns the bot's Telegram Star transactions in chronological order.
|
||||
|
||||
.. versionadded:: 21.4
|
||||
|
||||
Args:
|
||||
offset (:obj:`int`, optional): Number of transactions to skip in the response.
|
||||
limit (:obj:`int`, optional): The maximum number of transactions to be retrieved.
|
||||
Values between :tg-const:`telegram.constants.StarTransactionsLimit.MIN_LIMIT`-
|
||||
:tg-const:`telegram.constants.StarTransactionsLimit.MAX_LIMIT` are accepted.
|
||||
Defaults to :tg-const:`telegram.constants.StarTransactionsLimit.MAX_LIMIT`.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.StarTransactions`: On success.
|
||||
|
||||
Raises:
|
||||
:class:`telegram.error.TelegramError`
|
||||
"""
|
||||
|
||||
data: JSONDict = {"offset": offset, "limit": limit}
|
||||
|
||||
return StarTransactions.de_json( # type: ignore[return-value]
|
||||
await self._post(
|
||||
"getStarTransactions",
|
||||
data,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
),
|
||||
bot=self,
|
||||
)
|
||||
|
||||
async def send_paid_media(
|
||||
self,
|
||||
chat_id: Union[str, int],
|
||||
star_count: int,
|
||||
media: Sequence["InputPaidMedia"],
|
||||
caption: Optional[str] = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Optional[Sequence["MessageEntity"]] = None,
|
||||
show_caption_above_media: Optional[bool] = None,
|
||||
disable_notification: ODVInput[bool] = DEFAULT_NONE,
|
||||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
reply_markup: Optional[ReplyMarkup] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
*,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
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,
|
||||
) -> Message:
|
||||
"""Use this method to send paid media.
|
||||
|
||||
.. versionadded:: 21.4
|
||||
|
||||
Args:
|
||||
chat_id (:obj:`int` | :obj:`str`): |chat_id_channel| If the chat is a channel, all
|
||||
Telegram Star proceeds from this media will be credited to the chat's balance.
|
||||
Otherwise, they will be credited to the bot's balance.
|
||||
star_count (:obj:`int`): The number of Telegram Stars that must be paid to buy access
|
||||
to the media.
|
||||
media (Sequence[:class:`telegram.InputPaidMedia`]): A list describing the media to be
|
||||
sent; up to :tg-const:`telegram.constants.MediaGroupLimit.MAX_MEDIA_LENGTH` items.
|
||||
caption (:obj:`str`, optional): Caption of the media to be sent,
|
||||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters.
|
||||
parse_mode (:obj:`str`, optional): |parse_mode|
|
||||
caption_entities (Sequence[:class:`telegram.MessageEntity`], optional):
|
||||
|caption_entities|
|
||||
show_caption_above_media (:obj:`bool`, optional): Pass |show_cap_above_med|
|
||||
disable_notification (:obj:`bool`, optional): |disable_notification|
|
||||
protect_content (:obj:`bool`, optional): |protect_content|
|
||||
reply_parameters (:class:`telegram.ReplyParameters`, optional): |reply_parameters|
|
||||
reply_markup (:class:`InlineKeyboardMarkup` | :class:`ReplyKeyboardMarkup` | \
|
||||
:class:`ReplyKeyboardRemove` | :class:`ForceReply`, optional):
|
||||
Additional interface options. An object for an inline keyboard, custom reply
|
||||
keyboard, instructions to remove reply keyboard or to force a reply from the user.
|
||||
business_connection_id (:obj:`str`, optional): |business_id_str|
|
||||
|
||||
.. versionadded:: 21.5
|
||||
|
||||
Keyword Args:
|
||||
allow_sending_without_reply (:obj:`bool`, optional): |allow_sending_without_reply|
|
||||
Mutually exclusive with :paramref:`reply_parameters`, which this is a convenience
|
||||
parameter for
|
||||
|
||||
reply_to_message_id (:obj:`int`, optional): |reply_to_msg_id|
|
||||
Mutually exclusive with :paramref:`reply_parameters`, which this is a convenience
|
||||
parameter for
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, the sent message is returned.
|
||||
|
||||
Raises:
|
||||
:class:`telegram.error.TelegramError`
|
||||
"""
|
||||
|
||||
data: JSONDict = {
|
||||
"chat_id": chat_id,
|
||||
"star_count": star_count,
|
||||
"media": media,
|
||||
"show_caption_above_media": show_caption_above_media,
|
||||
}
|
||||
|
||||
return await self._send_message(
|
||||
"sendPaidMedia",
|
||||
data,
|
||||
caption=caption,
|
||||
parse_mode=parse_mode,
|
||||
caption_entities=caption_entities,
|
||||
disable_notification=disable_notification,
|
||||
protect_content=protect_content,
|
||||
reply_parameters=reply_parameters,
|
||||
reply_markup=reply_markup,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
reply_to_message_id=reply_to_message_id,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
business_connection_id=business_connection_id,
|
||||
)
|
||||
|
||||
async def create_chat_subscription_invite_link(
|
||||
self,
|
||||
chat_id: Union[str, int],
|
||||
subscription_period: int,
|
||||
subscription_price: int,
|
||||
name: Optional[str] = None,
|
||||
*,
|
||||
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,
|
||||
) -> ChatInviteLink:
|
||||
"""
|
||||
Use this method to create a `subscription invite link <https://telegram.org/blog/\
|
||||
superchannels-star-reactions-subscriptions#star-subscriptions>`_ for a channel chat.
|
||||
The bot must have the :attr:`~telegram.ChatPermissions.can_invite_users` administrator
|
||||
right. The link can be edited using the :meth:`edit_chat_subscription_invite_link` or
|
||||
revoked using the :meth:`revoke_chat_invite_link`.
|
||||
|
||||
.. versionadded:: 21.5
|
||||
|
||||
Args:
|
||||
chat_id (:obj:`int` | :obj:`str`): |chat_id_channel|
|
||||
subscription_period (:obj:`int`): The number of seconds the subscription will be
|
||||
active for before the next payment. Currently, it must always be
|
||||
:tg-const:`telegram.constants.ChatSubscriptionLimit.SUBSCRIPTION_PERIOD` (30 days).
|
||||
subscription_price (:obj:`int`): The number of Telegram Stars a user must pay initially
|
||||
and after each subsequent subscription period to be a member of the chat;
|
||||
:tg-const:`telegram.constants.ChatSubscriptionLimit.MIN_PRICE`-
|
||||
:tg-const:`telegram.constants.ChatSubscriptionLimit.MAX_PRICE`.
|
||||
name (:obj:`str`, optional): Invite link name;
|
||||
0-:tg-const:`telegram.constants.ChatInviteLinkLimit.NAME_LENGTH` characters.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.ChatInviteLink`
|
||||
|
||||
Raises:
|
||||
:class:`telegram.error.TelegramError`
|
||||
|
||||
"""
|
||||
data: JSONDict = {
|
||||
"chat_id": chat_id,
|
||||
"subscription_period": subscription_period,
|
||||
"subscription_price": subscription_price,
|
||||
"name": name,
|
||||
}
|
||||
|
||||
result = await self._post(
|
||||
"createChatSubscriptionInviteLink",
|
||||
data,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
return ChatInviteLink.de_json(result, self) # type: ignore[return-value]
|
||||
|
||||
async def edit_chat_subscription_invite_link(
|
||||
self,
|
||||
chat_id: Union[str, int],
|
||||
invite_link: Union[str, "ChatInviteLink"],
|
||||
name: Optional[str] = None,
|
||||
*,
|
||||
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,
|
||||
) -> ChatInviteLink:
|
||||
"""
|
||||
Use this method to edit a subscription invite link created by the bot. The bot must have
|
||||
:attr:`telegram.ChatPermissions.can_invite_users` administrator right.
|
||||
|
||||
.. versionadded:: 21.5
|
||||
|
||||
Args:
|
||||
chat_id (:obj:`int` | :obj:`str`): |chat_id_channel|
|
||||
invite_link (:obj:`str` | :obj:`telegram.ChatInviteLink`): The invite link to edit.
|
||||
name (:obj:`str`, optional): Invite link name;
|
||||
0-:tg-const:`telegram.constants.ChatInviteLinkLimit.NAME_LENGTH` characters.
|
||||
|
||||
Tip:
|
||||
Omitting this argument removes the name of the invite link.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.ChatInviteLink`
|
||||
|
||||
Raises:
|
||||
:class:`telegram.error.TelegramError`
|
||||
|
||||
"""
|
||||
link = invite_link.invite_link if isinstance(invite_link, ChatInviteLink) else invite_link
|
||||
data: JSONDict = {
|
||||
"chat_id": chat_id,
|
||||
"invite_link": link,
|
||||
"name": name,
|
||||
}
|
||||
|
||||
result = await self._post(
|
||||
"editChatSubscriptionInviteLink",
|
||||
data,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
return ChatInviteLink.de_json(result, self) # type: ignore[return-value]
|
||||
|
||||
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}
|
||||
@@ -9322,3 +9639,11 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||
"""Alias for :meth:`replace_sticker_in_set`"""
|
||||
refundStarPayment = refund_star_payment
|
||||
"""Alias for :meth:`refund_star_payment`"""
|
||||
getStarTransactions = get_star_transactions
|
||||
"""Alias for :meth:`get_star_transactions`"""
|
||||
sendPaidMedia = send_paid_media
|
||||
"""Alias for :meth:`send_paid_media`"""
|
||||
createChatSubscriptionInviteLink = create_chat_subscription_invite_link
|
||||
"""Alias for :meth:`create_chat_subscription_invite_link`"""
|
||||
editChatSubscriptionInviteLink = edit_chat_subscription_invite_link
|
||||
"""Alias for :meth:`edit_chat_subscription_invite_link`"""
|
||||
|
||||
@@ -84,13 +84,19 @@ class BotCommandScope(TelegramObject):
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["BotCommandScope"]:
|
||||
def de_json(
|
||||
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
|
||||
) -> Optional["BotCommandScope"]:
|
||||
"""Converts JSON data to the appropriate :class:`BotCommandScope` object, i.e. takes
|
||||
care of selecting the correct subclass.
|
||||
|
||||
Args:
|
||||
data (Dict[:obj:`str`, ...]): The JSON data.
|
||||
bot (:class:`telegram.Bot`): The bot associated with this object.
|
||||
bot (:class:`telegram.Bot`, optional): The bot associated with this object. Defaults to
|
||||
:obj:`None`, in which case shortcut methods will not be available.
|
||||
|
||||
.. versionchanged:: 21.4
|
||||
:paramref:`bot` is now optional and defaults to :obj:`None`
|
||||
|
||||
Returns:
|
||||
The Telegram object.
|
||||
|
||||
+15
-5
@@ -106,7 +106,9 @@ class BusinessConnection(TelegramObject):
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["BusinessConnection"]:
|
||||
def de_json(
|
||||
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
|
||||
) -> Optional["BusinessConnection"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
@@ -175,7 +177,9 @@ class BusinessMessagesDeleted(TelegramObject):
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["BusinessMessagesDeleted"]:
|
||||
def de_json(
|
||||
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
|
||||
) -> Optional["BusinessMessagesDeleted"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
@@ -232,7 +236,9 @@ class BusinessIntro(TelegramObject):
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["BusinessIntro"]:
|
||||
def de_json(
|
||||
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
|
||||
) -> Optional["BusinessIntro"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
@@ -284,7 +290,9 @@ class BusinessLocation(TelegramObject):
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["BusinessLocation"]:
|
||||
def de_json(
|
||||
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
|
||||
) -> Optional["BusinessLocation"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
@@ -431,7 +439,9 @@ class BusinessOpeningHours(TelegramObject):
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["BusinessOpeningHours"]:
|
||||
def de_json(
|
||||
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
|
||||
) -> Optional["BusinessOpeningHours"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ class CallbackQuery(TelegramObject):
|
||||
with the callback button that originated the query.
|
||||
|
||||
.. versionchanged:: 20.8
|
||||
Objects maybe be of type :class:`telegram.MaybeInaccessibleMessage` since Bot API
|
||||
Objects may be of type :class:`telegram.MaybeInaccessibleMessage` since Bot API
|
||||
7.0.
|
||||
data (:obj:`str` | :obj:`object`): Optional. Data associated with the callback button.
|
||||
Be aware that the message, which originated the query, can contain no callback buttons
|
||||
@@ -148,7 +148,9 @@ class CallbackQuery(TelegramObject):
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["CallbackQuery"]:
|
||||
def de_json(
|
||||
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
|
||||
) -> Optional["CallbackQuery"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
@@ -260,6 +262,8 @@ class CallbackQuery(TelegramObject):
|
||||
entities=entities,
|
||||
chat_id=None,
|
||||
message_id=None,
|
||||
# inline messages can not be sent on behalf of a bcid
|
||||
business_connection_id=None,
|
||||
)
|
||||
return await self._get_message().edit_text(
|
||||
text=text,
|
||||
@@ -328,6 +332,8 @@ class CallbackQuery(TelegramObject):
|
||||
chat_id=None,
|
||||
message_id=None,
|
||||
show_caption_above_media=show_caption_above_media,
|
||||
# inline messages can not be sent on behalf of a bcid
|
||||
business_connection_id=None,
|
||||
)
|
||||
return await self._get_message().edit_caption(
|
||||
caption=caption,
|
||||
@@ -388,6 +394,8 @@ class CallbackQuery(TelegramObject):
|
||||
api_kwargs=api_kwargs,
|
||||
chat_id=None,
|
||||
message_id=None,
|
||||
# inline messages can not be sent on behalf of a bcid
|
||||
business_connection_id=None,
|
||||
)
|
||||
return await self._get_message().edit_reply_markup(
|
||||
reply_markup=reply_markup,
|
||||
@@ -445,6 +453,8 @@ class CallbackQuery(TelegramObject):
|
||||
api_kwargs=api_kwargs,
|
||||
chat_id=None,
|
||||
message_id=None,
|
||||
# inline messages can not be sent on behalf of a bcid
|
||||
business_connection_id=None,
|
||||
)
|
||||
return await self._get_message().edit_media(
|
||||
media=media,
|
||||
@@ -516,6 +526,8 @@ class CallbackQuery(TelegramObject):
|
||||
live_period=live_period,
|
||||
chat_id=None,
|
||||
message_id=None,
|
||||
# inline messages can not be sent on behalf of a bcid
|
||||
business_connection_id=None,
|
||||
)
|
||||
return await self._get_message().edit_live_location(
|
||||
latitude=latitude,
|
||||
@@ -579,6 +591,8 @@ class CallbackQuery(TelegramObject):
|
||||
api_kwargs=api_kwargs,
|
||||
chat_id=None,
|
||||
message_id=None,
|
||||
# inline messages can not be sent on behalf of a bcid
|
||||
business_connection_id=None,
|
||||
)
|
||||
return await self._get_message().stop_live_location(
|
||||
reply_markup=reply_markup,
|
||||
|
||||
@@ -48,6 +48,7 @@ if TYPE_CHECKING:
|
||||
InputMediaDocument,
|
||||
InputMediaPhoto,
|
||||
InputMediaVideo,
|
||||
InputPaidMedia,
|
||||
InputPollOption,
|
||||
LabeledPrice,
|
||||
LinkPreviewOptions,
|
||||
@@ -904,6 +905,7 @@ class _ChatBase(TelegramObject):
|
||||
self,
|
||||
message_id: int,
|
||||
disable_notification: ODVInput[bool] = DEFAULT_NONE,
|
||||
business_connection_id: Optional[str] = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
@@ -931,11 +933,13 @@ class _ChatBase(TelegramObject):
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
business_connection_id=business_connection_id,
|
||||
)
|
||||
|
||||
async def unpin_message(
|
||||
self,
|
||||
message_id: Optional[int] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
@@ -962,6 +966,7 @@ class _ChatBase(TelegramObject):
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
message_id=message_id,
|
||||
business_connection_id=business_connection_id,
|
||||
)
|
||||
|
||||
async def unpin_all_messages(
|
||||
@@ -2661,6 +2666,81 @@ class _ChatBase(TelegramObject):
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
async def create_subscription_invite_link(
|
||||
self,
|
||||
subscription_period: int,
|
||||
subscription_price: int,
|
||||
name: Optional[str] = None,
|
||||
*,
|
||||
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,
|
||||
) -> "ChatInviteLink":
|
||||
"""Shortcut for::
|
||||
|
||||
await bot.create_chat_subscription_invite_link(
|
||||
chat_id=update.effective_chat.id, *args, **kwargs
|
||||
)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.create_chat_subscription_invite_link`.
|
||||
|
||||
.. versionadded:: 21.5
|
||||
|
||||
Returns:
|
||||
:class:`telegram.ChatInviteLink`
|
||||
"""
|
||||
return await self.get_bot().create_chat_subscription_invite_link(
|
||||
chat_id=self.id,
|
||||
subscription_period=subscription_period,
|
||||
subscription_price=subscription_price,
|
||||
name=name,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
async def edit_subscription_invite_link(
|
||||
self,
|
||||
invite_link: Union[str, "ChatInviteLink"],
|
||||
name: Optional[str] = None,
|
||||
*,
|
||||
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,
|
||||
) -> "ChatInviteLink":
|
||||
"""Shortcut for::
|
||||
|
||||
await bot.edit_chat_subscription_invite_link(
|
||||
chat_id=update.effective_chat.id, *args, **kwargs
|
||||
)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.edit_chat_subscription_invite_link`.
|
||||
|
||||
.. versionadded:: 21.5
|
||||
|
||||
Returns:
|
||||
:class:`telegram.ChatInviteLink`
|
||||
|
||||
"""
|
||||
return await self.get_bot().edit_chat_subscription_invite_link(
|
||||
chat_id=self.id,
|
||||
invite_link=invite_link,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
name=name,
|
||||
)
|
||||
|
||||
async def approve_join_request(
|
||||
self,
|
||||
user_id: int,
|
||||
@@ -3257,6 +3337,62 @@ class _ChatBase(TelegramObject):
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
async def send_paid_media(
|
||||
self,
|
||||
star_count: int,
|
||||
media: Sequence["InputPaidMedia"],
|
||||
caption: Optional[str] = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Optional[Sequence["MessageEntity"]] = None,
|
||||
show_caption_above_media: Optional[bool] = None,
|
||||
disable_notification: ODVInput[bool] = DEFAULT_NONE,
|
||||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_parameters: Optional["ReplyParameters"] = None,
|
||||
reply_markup: Optional[ReplyMarkup] = None,
|
||||
business_connection_id: Optional[str] = None,
|
||||
*,
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
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,
|
||||
) -> "Message":
|
||||
"""Shortcut for::
|
||||
|
||||
await bot.send_paid_media(chat_id=update.effective_chat.id, *args, **kwargs)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.send_paid_media`.
|
||||
|
||||
.. versionadded:: 21.4
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, instance representing the message posted.
|
||||
"""
|
||||
return await self.get_bot().send_paid_media(
|
||||
chat_id=self.id,
|
||||
star_count=star_count,
|
||||
media=media,
|
||||
caption=caption,
|
||||
parse_mode=parse_mode,
|
||||
caption_entities=caption_entities,
|
||||
show_caption_above_media=show_caption_above_media,
|
||||
disable_notification=disable_notification,
|
||||
protect_content=protect_content,
|
||||
reply_parameters=reply_parameters,
|
||||
reply_markup=reply_markup,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
reply_to_message_id=reply_to_message_id,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
business_connection_id=business_connection_id,
|
||||
)
|
||||
|
||||
|
||||
class Chat(_ChatBase):
|
||||
"""This object represents a chat.
|
||||
|
||||
+19
-13
@@ -78,7 +78,9 @@ class BackgroundFill(TelegramObject):
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["BackgroundFill"]:
|
||||
def de_json(
|
||||
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
|
||||
) -> Optional["BackgroundFill"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
@@ -267,7 +269,9 @@ class BackgroundType(TelegramObject):
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["BackgroundType"]:
|
||||
def de_json(
|
||||
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
|
||||
) -> Optional["BackgroundType"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
@@ -303,7 +307,7 @@ class BackgroundTypeFill(BackgroundType):
|
||||
.. versionadded:: 21.2
|
||||
|
||||
Args:
|
||||
fill (:obj:`telegram.BackgroundFill`): The background fill.
|
||||
fill (:class:`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`.
|
||||
@@ -311,7 +315,7 @@ class BackgroundTypeFill(BackgroundType):
|
||||
Attributes:
|
||||
type (:obj:`str`): Type of the background. Always
|
||||
:attr:`~telegram.BackgroundType.FILL`.
|
||||
fill (:obj:`telegram.BackgroundFill`): The background fill.
|
||||
fill (:class:`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`.
|
||||
@@ -345,7 +349,7 @@ class BackgroundTypeWallpaper(BackgroundType):
|
||||
.. versionadded:: 21.2
|
||||
|
||||
Args:
|
||||
document (:obj:`telegram.Document`): Document with the wallpaper
|
||||
document (:class:`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`.
|
||||
@@ -357,7 +361,7 @@ class BackgroundTypeWallpaper(BackgroundType):
|
||||
Attributes:
|
||||
type (:obj:`str`): Type of the background. Always
|
||||
:attr:`~telegram.BackgroundType.WALLPAPER`.
|
||||
document (:obj:`telegram.Document`): Document with the wallpaper
|
||||
document (:class:`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`.
|
||||
@@ -403,8 +407,8 @@ class BackgroundTypePattern(BackgroundType):
|
||||
.. versionadded:: 21.2
|
||||
|
||||
Args:
|
||||
document (:obj:`telegram.Document`): Document with the pattern.
|
||||
fill (:obj:`telegram.BackgroundFill`): The background fill that is combined with
|
||||
document (:class:`telegram.Document`): Document with the pattern.
|
||||
fill (:class:`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;
|
||||
@@ -418,8 +422,8 @@ class BackgroundTypePattern(BackgroundType):
|
||||
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
|
||||
document (:class:`telegram.Document`): Document with the pattern.
|
||||
fill (:class:`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;
|
||||
@@ -507,10 +511,10 @@ class ChatBackground(TelegramObject):
|
||||
.. versionadded:: 21.2
|
||||
|
||||
Args:
|
||||
type (:obj:`telegram.BackgroundType`): Type of the background.
|
||||
type (:class:`telegram.BackgroundType`): Type of the background.
|
||||
|
||||
Attributes:
|
||||
type (:obj:`telegram.BackgroundType`): Type of the background.
|
||||
type (:class:`telegram.BackgroundType`): Type of the background.
|
||||
"""
|
||||
|
||||
__slots__ = ("type",)
|
||||
@@ -528,7 +532,9 @@ class ChatBackground(TelegramObject):
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["ChatBackground"]:
|
||||
def de_json(
|
||||
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
|
||||
) -> Optional["ChatBackground"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
|
||||
+15
-5
@@ -110,7 +110,9 @@ class ChatBoostSource(TelegramObject):
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["ChatBoostSource"]:
|
||||
def de_json(
|
||||
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
|
||||
) -> Optional["ChatBoostSource"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
@@ -275,7 +277,9 @@ class ChatBoost(TelegramObject):
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["ChatBoost"]:
|
||||
def de_json(
|
||||
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
|
||||
) -> Optional["ChatBoost"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
@@ -325,7 +329,9 @@ class ChatBoostUpdated(TelegramObject):
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["ChatBoostUpdated"]:
|
||||
def de_json(
|
||||
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
|
||||
) -> Optional["ChatBoostUpdated"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
@@ -382,7 +388,9 @@ class ChatBoostRemoved(TelegramObject):
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["ChatBoostRemoved"]:
|
||||
def de_json(
|
||||
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
|
||||
) -> Optional["ChatBoostRemoved"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
@@ -429,7 +437,9 @@ class UserChatBoosts(TelegramObject):
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["UserChatBoosts"]:
|
||||
def de_json(
|
||||
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
|
||||
) -> Optional["UserChatBoosts"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
|
||||
+28
-13
@@ -78,7 +78,7 @@ class ChatFullInfo(_ChatBase):
|
||||
#collectible-usernames>`_; for private chats, supergroups and channels.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
birthdate (:obj:`telegram.Birthdate`, optional): For private chats,
|
||||
birthdate (:class:`telegram.Birthdate`, optional): For private chats,
|
||||
the date of birth of the user.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
@@ -94,8 +94,8 @@ class ChatFullInfo(_ChatBase):
|
||||
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.
|
||||
personal_chat (:class:`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
|
||||
@@ -121,7 +121,8 @@ class ChatFullInfo(_ChatBase):
|
||||
|
||||
.. 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.
|
||||
emoji status of the chat or the other party in a private chat, as a datetime object,
|
||||
if any.
|
||||
|
||||
|datetime_localization|
|
||||
|
||||
@@ -194,6 +195,10 @@ class ChatFullInfo(_ChatBase):
|
||||
chats.
|
||||
location (:class:`telegram.ChatLocation`, optional): For supergroups, the location to which
|
||||
the supergroup is connected.
|
||||
can_send_paid_media (:obj:`bool`, optional): :obj:`True`, if paid media messages can be
|
||||
sent or forwarded to the channel chat. The field is available only for channel chats.
|
||||
|
||||
.. versionadded:: 21.4
|
||||
|
||||
Attributes:
|
||||
id (:obj:`int`): Unique identifier for this chat.
|
||||
@@ -227,7 +232,7 @@ class ChatFullInfo(_ChatBase):
|
||||
obtained via :meth:`~telegram.Bot.get_chat`.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
birthdate (:obj:`telegram.Birthdate`): Optional. For private chats,
|
||||
birthdate (:class:`telegram.Birthdate`): Optional. For private chats,
|
||||
the date of birth of the user.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
@@ -243,8 +248,8 @@ class ChatFullInfo(_ChatBase):
|
||||
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.
|
||||
personal_chat (:class:`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
|
||||
@@ -270,7 +275,8 @@ class ChatFullInfo(_ChatBase):
|
||||
|
||||
.. 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.
|
||||
emoji status of the chat or the other party in a private chat, as a datetime object,
|
||||
if any.
|
||||
|
||||
|datetime_localization|
|
||||
|
||||
@@ -343,6 +349,10 @@ class ChatFullInfo(_ChatBase):
|
||||
chats.
|
||||
location (:class:`telegram.ChatLocation`): Optional. For supergroups, the location to which
|
||||
the supergroup is connected.
|
||||
can_send_paid_media (:obj:`bool`): Optional. :obj:`True`, if paid media messages can be
|
||||
sent or forwarded to the channel chat. The field is available only for channel chats.
|
||||
|
||||
.. versionadded:: 21.4
|
||||
|
||||
.. _accent colors: https://core.telegram.org/bots/api#accent-colors
|
||||
.. _topics: https://telegram.org/blog/topics-in-groups-collectible-usernames#topics-in-groups
|
||||
@@ -358,6 +368,7 @@ class ChatFullInfo(_ChatBase):
|
||||
"business_intro",
|
||||
"business_location",
|
||||
"business_opening_hours",
|
||||
"can_send_paid_media",
|
||||
"can_set_sticker_set",
|
||||
"custom_emoji_sticker_set_name",
|
||||
"description",
|
||||
@@ -432,6 +443,7 @@ class ChatFullInfo(_ChatBase):
|
||||
custom_emoji_sticker_set_name: Optional[str] = None,
|
||||
linked_chat_id: Optional[int] = None,
|
||||
location: Optional[ChatLocation] = None,
|
||||
can_send_paid_media: Optional[bool] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
@@ -490,13 +502,16 @@ class ChatFullInfo(_ChatBase):
|
||||
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
|
||||
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
|
||||
self.can_send_paid_media: Optional[bool] = can_send_paid_media
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["ChatFullInfo"]:
|
||||
def de_json(
|
||||
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
|
||||
) -> Optional["ChatFullInfo"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
|
||||
@@ -69,6 +69,16 @@ class ChatInviteLink(TelegramObject):
|
||||
created using this link.
|
||||
|
||||
.. versionadded:: 13.8
|
||||
subscription_period (:obj:`int`, optional): The number of seconds the subscription will be
|
||||
active for before the next payment.
|
||||
|
||||
.. versionadded:: 21.5
|
||||
subscription_price (:obj:`int`, optional): The amount of Telegram Stars a user must pay
|
||||
initially and after each subsequent subscription period to be a member of the chat
|
||||
using the link.
|
||||
|
||||
.. versionadded:: 21.5
|
||||
|
||||
Attributes:
|
||||
invite_link (:obj:`str`): The invite link. If the link was created by another chat
|
||||
administrator, then the second part of the link will be replaced with ``'…'``.
|
||||
@@ -96,6 +106,15 @@ class ChatInviteLink(TelegramObject):
|
||||
created using this link.
|
||||
|
||||
.. versionadded:: 13.8
|
||||
subscription_period (:obj:`int`): Optional. The number of seconds the subscription will be
|
||||
active for before the next payment.
|
||||
|
||||
.. versionadded:: 21.5
|
||||
subscription_price (:obj:`int`): Optional. The amount of Telegram Stars a user must pay
|
||||
initially and after each subsequent subscription period to be a member of the chat
|
||||
using the link.
|
||||
|
||||
.. versionadded:: 21.5
|
||||
|
||||
"""
|
||||
|
||||
@@ -109,6 +128,8 @@ class ChatInviteLink(TelegramObject):
|
||||
"member_limit",
|
||||
"name",
|
||||
"pending_join_request_count",
|
||||
"subscription_period",
|
||||
"subscription_price",
|
||||
)
|
||||
|
||||
def __init__(
|
||||
@@ -122,6 +143,8 @@ class ChatInviteLink(TelegramObject):
|
||||
member_limit: Optional[int] = None,
|
||||
name: Optional[str] = None,
|
||||
pending_join_request_count: Optional[int] = None,
|
||||
subscription_period: Optional[int] = None,
|
||||
subscription_price: Optional[int] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
@@ -140,6 +163,9 @@ class ChatInviteLink(TelegramObject):
|
||||
self.pending_join_request_count: Optional[int] = (
|
||||
int(pending_join_request_count) if pending_join_request_count is not None else None
|
||||
)
|
||||
self.subscription_period: Optional[int] = subscription_period
|
||||
self.subscription_price: Optional[int] = subscription_price
|
||||
|
||||
self._id_attrs = (
|
||||
self.invite_link,
|
||||
self.creates_join_request,
|
||||
@@ -151,7 +177,9 @@ class ChatInviteLink(TelegramObject):
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["ChatInviteLink"]:
|
||||
def de_json(
|
||||
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
|
||||
) -> Optional["ChatInviteLink"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
|
||||
@@ -129,7 +129,9 @@ class ChatJoinRequest(TelegramObject):
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["ChatJoinRequest"]:
|
||||
def de_json(
|
||||
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
|
||||
) -> Optional["ChatJoinRequest"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
|
||||
@@ -68,7 +68,9 @@ class ChatLocation(TelegramObject):
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["ChatLocation"]:
|
||||
def de_json(
|
||||
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
|
||||
) -> Optional["ChatLocation"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
|
||||
+16
-3
@@ -17,6 +17,7 @@
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram ChatMember."""
|
||||
|
||||
import datetime
|
||||
from typing import TYPE_CHECKING, Dict, Final, Optional, Type
|
||||
|
||||
@@ -104,7 +105,9 @@ class ChatMember(TelegramObject):
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["ChatMember"]:
|
||||
def de_json(
|
||||
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
|
||||
) -> Optional["ChatMember"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
@@ -389,24 +392,34 @@ class ChatMemberMember(ChatMember):
|
||||
|
||||
Args:
|
||||
user (:class:`telegram.User`): Information about the user.
|
||||
until_date (:class:`datetime.datetime`, optional): Date when the user's subscription will
|
||||
expire.
|
||||
|
||||
.. versionadded:: 21.5
|
||||
|
||||
Attributes:
|
||||
status (:obj:`str`): The member's status in the chat,
|
||||
always :tg-const:`telegram.ChatMember.MEMBER`.
|
||||
user (:class:`telegram.User`): Information about the user.
|
||||
until_date (:class:`datetime.datetime`): Optional. Date when the user's subscription will
|
||||
expire.
|
||||
|
||||
.. versionadded:: 21.5
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = ()
|
||||
__slots__ = ("until_date",)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
user: User,
|
||||
until_date: Optional[datetime.datetime] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(status=ChatMember.MEMBER, user=user, api_kwargs=api_kwargs)
|
||||
self._freeze()
|
||||
with self._unfrozen():
|
||||
self.until_date: Optional[datetime.datetime] = until_date
|
||||
|
||||
|
||||
class ChatMemberRestricted(ChatMember):
|
||||
|
||||
@@ -141,7 +141,9 @@ class ChatMemberUpdated(TelegramObject):
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["ChatMemberUpdated"]:
|
||||
def de_json(
|
||||
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
|
||||
) -> Optional["ChatMemberUpdated"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
|
||||
@@ -231,7 +231,9 @@ class ChatPermissions(TelegramObject):
|
||||
return cls(*(14 * (False,)))
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["ChatPermissions"]:
|
||||
def de_json(
|
||||
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
|
||||
) -> Optional["ChatPermissions"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
|
||||
@@ -92,7 +92,9 @@ class ChosenInlineResult(TelegramObject):
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["ChosenInlineResult"]:
|
||||
def de_json(
|
||||
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
|
||||
) -> Optional["ChosenInlineResult"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ class _BaseThumbedMedium(_BaseMedium):
|
||||
is supposed to be the same over time and for different bots.
|
||||
Can't be used to download or reuse the file.
|
||||
file_size (:obj:`int`, optional): File size.
|
||||
thumbnail (:class:`telegram.PhotoSize`, optional): Thumbnail as defined by sender.
|
||||
thumbnail (:class:`telegram.PhotoSize`, optional): Thumbnail as defined by the sender.
|
||||
|
||||
.. versionadded:: 20.2
|
||||
|
||||
@@ -54,7 +54,7 @@ class _BaseThumbedMedium(_BaseMedium):
|
||||
is supposed to be the same over time and for different bots.
|
||||
Can't be used to download or reuse the file.
|
||||
file_size (:obj:`int`): Optional. File size.
|
||||
thumbnail (:class:`telegram.PhotoSize`): Optional. Thumbnail as defined by sender.
|
||||
thumbnail (:class:`telegram.PhotoSize`): Optional. Thumbnail as defined by the sender.
|
||||
|
||||
.. versionadded:: 20.2
|
||||
|
||||
@@ -82,7 +82,7 @@ class _BaseThumbedMedium(_BaseMedium):
|
||||
|
||||
@classmethod
|
||||
def de_json(
|
||||
cls: Type[ThumbedMT_co], data: Optional[JSONDict], bot: "Bot"
|
||||
cls: Type[ThumbedMT_co], data: Optional[JSONDict], bot: Optional["Bot"] = None
|
||||
) -> Optional[ThumbedMT_co]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
@@ -39,11 +39,11 @@ class Animation(_BaseThumbedMedium):
|
||||
file_unique_id (:obj:`str`): Unique identifier for this file, which
|
||||
is supposed to be the same over time and for different bots.
|
||||
Can't be used to download or reuse the file.
|
||||
width (:obj:`int`): Video width as defined by sender.
|
||||
height (:obj:`int`): Video height as defined by sender.
|
||||
duration (:obj:`int`): Duration of the video in seconds as defined by sender.
|
||||
file_name (:obj:`str`, optional): Original animation filename as defined by sender.
|
||||
mime_type (:obj:`str`, optional): MIME type of the file as defined by sender.
|
||||
width (:obj:`int`): Video width as defined by the sender.
|
||||
height (:obj:`int`): Video height as defined by the sender.
|
||||
duration (:obj:`int`): Duration of the video in seconds as defined by the sender.
|
||||
file_name (:obj:`str`, optional): Original animation filename as defined by the sender.
|
||||
mime_type (:obj:`str`, optional): MIME type of the file as defined by the sender.
|
||||
file_size (:obj:`int`, optional): File size in bytes.
|
||||
thumbnail (:class:`telegram.PhotoSize`, optional): Animation thumbnail as defined by
|
||||
sender.
|
||||
@@ -56,11 +56,11 @@ class Animation(_BaseThumbedMedium):
|
||||
file_unique_id (:obj:`str`): Unique identifier for this file, which
|
||||
is supposed to be the same over time and for different bots.
|
||||
Can't be used to download or reuse the file.
|
||||
width (:obj:`int`): Video width as defined by sender.
|
||||
height (:obj:`int`): Video height as defined by sender.
|
||||
duration (:obj:`int`): Duration of the video in seconds as defined by sender.
|
||||
file_name (:obj:`str`): Optional. Original animation filename as defined by sender.
|
||||
mime_type (:obj:`str`): Optional. MIME type of the file as defined by sender.
|
||||
width (:obj:`int`): Video width as defined by the sender.
|
||||
height (:obj:`int`): Video height as defined by the sender.
|
||||
duration (:obj:`int`): Duration of the video in seconds as defined by the sender.
|
||||
file_name (:obj:`str`): Optional. Original animation filename as defined by the sender.
|
||||
mime_type (:obj:`str`): Optional. MIME type of the file as defined by the sender.
|
||||
file_size (:obj:`int`): Optional. File size in bytes.
|
||||
thumbnail (:class:`telegram.PhotoSize`): Optional. Animation thumbnail as defined by
|
||||
sender.
|
||||
|
||||
+12
-12
@@ -39,12 +39,12 @@ class Audio(_BaseThumbedMedium):
|
||||
or reuse the file.
|
||||
file_unique_id (:obj:`str`): Unique identifier for this file, which is supposed to be
|
||||
the same over time and for different bots. Can't be used to download or reuse the file.
|
||||
duration (:obj:`int`): Duration of the audio in seconds as defined by sender.
|
||||
performer (:obj:`str`, optional): Performer of the audio as defined by sender or by audio
|
||||
tags.
|
||||
title (:obj:`str`, optional): Title of the audio as defined by sender or by audio tags.
|
||||
file_name (:obj:`str`, optional): Original filename as defined by sender.
|
||||
mime_type (:obj:`str`, optional): MIME type of the file as defined by sender.
|
||||
duration (:obj:`int`): Duration of the audio in seconds as defined by the sender.
|
||||
performer (:obj:`str`, optional): Performer of the audio as defined by the sender or by
|
||||
audio tags.
|
||||
title (:obj:`str`, optional): Title of the audio as defined by the sender or by audio tags.
|
||||
file_name (:obj:`str`, optional): Original filename as defined by the sender.
|
||||
mime_type (:obj:`str`, optional): MIME type of the file as defined by the sender.
|
||||
file_size (:obj:`int`, optional): File size in bytes.
|
||||
thumbnail (:class:`telegram.PhotoSize`, optional): Thumbnail of the album cover to
|
||||
which the music file belongs.
|
||||
@@ -56,12 +56,12 @@ class Audio(_BaseThumbedMedium):
|
||||
or reuse the file.
|
||||
file_unique_id (:obj:`str`): Unique identifier for this file, which is supposed to be
|
||||
the same over time and for different bots. Can't be used to download or reuse the file.
|
||||
duration (:obj:`int`): Duration of the audio in seconds as defined by sender.
|
||||
performer (:obj:`str`): Optional. Performer of the audio as defined by sender or by audio
|
||||
tags.
|
||||
title (:obj:`str`): Optional. Title of the audio as defined by sender or by audio tags.
|
||||
file_name (:obj:`str`): Optional. Original filename as defined by sender.
|
||||
mime_type (:obj:`str`): Optional. MIME type of the file as defined by sender.
|
||||
duration (:obj:`int`): Duration of the audio in seconds as defined by the sender.
|
||||
performer (:obj:`str`): Optional. Performer of the audio as defined by the sender or by
|
||||
audio tags.
|
||||
title (:obj:`str`): Optional. Title of the audio as defined by the sender or by audio tags.
|
||||
file_name (:obj:`str`): Optional. Original filename as defined by the sender.
|
||||
mime_type (:obj:`str`): Optional. MIME type of the file as defined by the sender.
|
||||
file_size (:obj:`int`): Optional. File size in bytes.
|
||||
thumbnail (:class:`telegram.PhotoSize`): Optional. Thumbnail of the album cover to
|
||||
which the music file belongs.
|
||||
|
||||
@@ -39,10 +39,11 @@ class Document(_BaseThumbedMedium):
|
||||
or reuse the file.
|
||||
file_unique_id (:obj:`str`): Unique identifier for this file, which is supposed to be
|
||||
the same over time and for different bots. Can't be used to download or reuse the file.
|
||||
file_name (:obj:`str`, optional): Original filename as defined by sender.
|
||||
mime_type (:obj:`str`, optional): MIME type of the file as defined by sender.
|
||||
file_name (:obj:`str`, optional): Original filename as defined by the sender.
|
||||
mime_type (:obj:`str`, optional): MIME type of the file as defined by the sender.
|
||||
file_size (:obj:`int`, optional): File size in bytes.
|
||||
thumbnail (:class:`telegram.PhotoSize`, optional): Document thumbnail as defined by sender.
|
||||
thumbnail (:class:`telegram.PhotoSize`, optional): Document thumbnail as defined by the
|
||||
sender.
|
||||
|
||||
.. versionadded:: 20.2
|
||||
|
||||
@@ -51,10 +52,11 @@ class Document(_BaseThumbedMedium):
|
||||
or reuse the file.
|
||||
file_unique_id (:obj:`str`): Unique identifier for this file, which is supposed to be
|
||||
the same over time and for different bots. Can't be used to download or reuse the file.
|
||||
file_name (:obj:`str`): Optional. Original filename as defined by sender.
|
||||
mime_type (:obj:`str`): Optional. MIME type of the file as defined by sender.
|
||||
file_name (:obj:`str`): Optional. Original filename as defined by the sender.
|
||||
mime_type (:obj:`str`): Optional. MIME type of the file as defined by the sender.
|
||||
file_size (:obj:`int`): Optional. File size in bytes.
|
||||
thumbnail (:class:`telegram.PhotoSize`): Optional. Document thumbnail as defined by sender.
|
||||
thumbnail (:class:`telegram.PhotoSize`): Optional. Document thumbnail as defined by the
|
||||
sender.
|
||||
|
||||
.. versionadded:: 20.2
|
||||
|
||||
|
||||
@@ -22,7 +22,8 @@ import mimetypes
|
||||
from typing import IO, Optional, Union
|
||||
from uuid import uuid4
|
||||
|
||||
from telegram._utils.files import load_file
|
||||
from telegram._utils.files import guess_file_name, load_file
|
||||
from telegram._utils.strings import TextEncoding
|
||||
from telegram._utils.types import FieldTuple
|
||||
|
||||
_DEFAULT_MIME_TYPE = "application/octet-stream"
|
||||
@@ -52,9 +53,36 @@ class InputFile:
|
||||
attach (:obj:`bool`, optional): Pass :obj:`True` if the parameter this file belongs to in
|
||||
the request to Telegram should point to the multipart data via an ``attach://`` URI.
|
||||
Defaults to `False`.
|
||||
read_file_handle (:obj:`bool`, optional): If :obj:`True` and :paramref:`obj` is a file
|
||||
handle, the data will be read from the file handle on initialization of this object.
|
||||
If :obj:`False`, the file handle will be passed on to the
|
||||
`networking backend <telegram.request.BaseRequest.do_request>`_ which will have to
|
||||
handle the reading. Defaults to :obj:`True`.
|
||||
|
||||
Tip:
|
||||
If you upload extremely large files, you may want to set this to :obj:`False` to
|
||||
avoid reading the complete file into memory. Additionally, this may be supported
|
||||
better by the networking backend (in particular it is handled better by
|
||||
the default :class:`~telegram.request.HTTPXRequest`).
|
||||
|
||||
Important:
|
||||
If you set this to :obj:`False`, you have to ensure that the file handle is still
|
||||
open when the request is made. In particular, the following snippet can *not* work
|
||||
as expected.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
with open('file.txt', 'rb') as file:
|
||||
input_file = InputFile(file, read_file_handle=False)
|
||||
|
||||
# here the file handle is already closed and the upload will fail
|
||||
await bot.send_document(chat_id, input_file)
|
||||
|
||||
.. versionadded:: 21.5
|
||||
|
||||
|
||||
Attributes:
|
||||
input_file_content (:obj:`bytes`): The binary content of the file to send.
|
||||
input_file_content (:obj:`bytes` | :class:`IO`): The binary content of the file to send.
|
||||
attach_name (:obj:`str`): Optional. If present, the parameter this file belongs to in
|
||||
the request to Telegram should point to the multipart data via a an URI of the form
|
||||
``attach://<attach_name>`` URI.
|
||||
@@ -70,14 +98,18 @@ class InputFile:
|
||||
obj: Union[IO[bytes], bytes, str],
|
||||
filename: Optional[str] = None,
|
||||
attach: bool = False,
|
||||
read_file_handle: bool = True,
|
||||
):
|
||||
if isinstance(obj, bytes):
|
||||
self.input_file_content: bytes = obj
|
||||
self.input_file_content: Union[bytes, IO[bytes]] = obj
|
||||
elif isinstance(obj, str):
|
||||
self.input_file_content = obj.encode("utf-8")
|
||||
else:
|
||||
self.input_file_content = obj.encode(TextEncoding.UTF_8)
|
||||
elif read_file_handle:
|
||||
reported_filename, self.input_file_content = load_file(obj)
|
||||
filename = filename or reported_filename
|
||||
else:
|
||||
self.input_file_content = obj
|
||||
filename = filename or guess_file_name(obj)
|
||||
|
||||
self.attach_name: Optional[str] = "attached" + uuid4().hex if attach else None
|
||||
|
||||
@@ -94,8 +126,11 @@ class InputFile:
|
||||
def field_tuple(self) -> FieldTuple:
|
||||
"""Field tuple representing the contents of the file for upload to the Telegram servers.
|
||||
|
||||
.. versionchanged:: 21.5
|
||||
Content may now be a file handle.
|
||||
|
||||
Returns:
|
||||
Tuple[:obj:`str`, :obj:`bytes`, :obj:`str`]:
|
||||
Tuple[:obj:`str`, :obj:`bytes` | :class:`IO`, :obj:`str`]:
|
||||
"""
|
||||
return self.filename, self.input_file_content, self.mimetype
|
||||
|
||||
|
||||
+172
-22
@@ -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/].
|
||||
"""Base class for Telegram InputMedia Objects."""
|
||||
from typing import Optional, Sequence, Tuple, Union
|
||||
from typing import Final, Optional, Sequence, Tuple, Union
|
||||
|
||||
from telegram import constants
|
||||
from telegram._files.animation import Animation
|
||||
@@ -50,8 +50,8 @@ class InputMedia(TelegramObject):
|
||||
|
||||
Args:
|
||||
media_type (:obj:`str`): Type of media that the instance represents.
|
||||
media (:obj:`str` | :term:`file object` | :obj:`bytes` | :class:`pathlib.Path` | \
|
||||
:class:`telegram.Animation` | :class:`telegram.Audio` | \
|
||||
media (:obj:`str` | :term:`file object` | :class:`~telegram.InputFile` | :obj:`bytes` | \
|
||||
:class:`pathlib.Path` | :class:`telegram.Animation` | :class:`telegram.Audio` | \
|
||||
:class:`telegram.Document` | :class:`telegram.PhotoSize` | \
|
||||
:class:`telegram.Video`): File to send.
|
||||
|fileinputnopath|
|
||||
@@ -115,13 +115,163 @@ class InputMedia(TelegramObject):
|
||||
)
|
||||
|
||||
|
||||
class InputPaidMedia(TelegramObject):
|
||||
"""
|
||||
Base class for Telegram InputPaidMedia Objects. Currently, it can be one of:
|
||||
|
||||
* :class:`telegram.InputMediaPhoto`
|
||||
* :class:`telegram.InputMediaVideo`
|
||||
|
||||
.. seealso:: :wiki:`Working with Files and Media <Working-with-Files-and-Media>`
|
||||
|
||||
.. versionadded:: 21.4
|
||||
|
||||
Args:
|
||||
type (:obj:`str`): Type of media that the instance represents.
|
||||
media (:obj:`str` | :term:`file object` | :class:`~telegram.InputFile` | :obj:`bytes` | \
|
||||
:class:`pathlib.Path` | :class:`telegram.PhotoSize` | :class:`telegram.Video`): File
|
||||
to send. |fileinputnopath|
|
||||
Lastly you can pass an existing telegram media object of the corresponding type
|
||||
to send.
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): Type of the input media.
|
||||
media (:obj:`str` | :class:`telegram.InputFile`): Media to send.
|
||||
"""
|
||||
|
||||
PHOTO: Final[str] = constants.InputPaidMediaType.PHOTO
|
||||
""":const:`telegram.constants.InputPaidMediaType.PHOTO`"""
|
||||
VIDEO: Final[str] = constants.InputPaidMediaType.VIDEO
|
||||
""":const:`telegram.constants.InputPaidMediaType.VIDEO`"""
|
||||
|
||||
__slots__ = ("media", "type")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
type: str, # pylint: disable=redefined-builtin
|
||||
media: Union[str, InputFile, PhotoSize, Video],
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
self.type: str = enum.get_member(constants.InputPaidMediaType, type, type)
|
||||
self.media: Union[str, InputFile, PhotoSize, Video] = media
|
||||
|
||||
self._freeze()
|
||||
|
||||
|
||||
class InputPaidMediaPhoto(InputPaidMedia):
|
||||
"""The paid media to send is a photo.
|
||||
|
||||
.. seealso:: :wiki:`Working with Files and Media <Working-with-Files-and-Media>`
|
||||
|
||||
.. versionadded:: 21.4
|
||||
|
||||
Args:
|
||||
media (:obj:`str` | :term:`file object` | :class:`~telegram.InputFile` | :obj:`bytes` | \
|
||||
:class:`pathlib.Path` | :class:`telegram.PhotoSize`): File to send. |fileinputnopath|
|
||||
Lastly you can pass an existing :class:`telegram.PhotoSize` object to send.
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): Type of the media, always
|
||||
:tg-const:`telegram.constants.InputPaidMediaType.PHOTO`.
|
||||
media (:obj:`str` | :class:`telegram.InputFile`): Photo to send.
|
||||
"""
|
||||
|
||||
__slots__ = ()
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
media: Union[FileInput, PhotoSize],
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
media = parse_file_input(media, PhotoSize, attach=True, local_mode=True)
|
||||
super().__init__(type=InputPaidMedia.PHOTO, media=media, api_kwargs=api_kwargs)
|
||||
self._freeze()
|
||||
|
||||
|
||||
class InputPaidMediaVideo(InputPaidMedia):
|
||||
"""
|
||||
The paid media to send is a video.
|
||||
|
||||
.. seealso:: :wiki:`Working with Files and Media <Working-with-Files-and-Media>`
|
||||
|
||||
.. versionadded:: 21.4
|
||||
|
||||
Note:
|
||||
* When using a :class:`telegram.Video` for the :attr:`media` attribute, it will take the
|
||||
width, height and duration from that video, unless otherwise specified with the optional
|
||||
arguments.
|
||||
* :paramref:`thumbnail` will be ignored for small video files, for which Telegram can
|
||||
easily generate thumbnails. However, this behaviour is undocumented and might be
|
||||
changed by Telegram.
|
||||
|
||||
Args:
|
||||
media (:obj:`str` | :term:`file object` | :class:`~telegram.InputFile` | :obj:`bytes` | \
|
||||
:class:`pathlib.Path` | :class:`telegram.Video`): File to send. |fileinputnopath|
|
||||
Lastly you can pass an existing :class:`telegram.Video` object to send.
|
||||
thumbnail (:term:`file object` | :obj:`bytes` | :class:`pathlib.Path` | :obj:`str`, \
|
||||
optional): |thumbdocstringnopath|
|
||||
width (:obj:`int`, optional): Video width.
|
||||
height (:obj:`int`, optional): Video height.
|
||||
duration (:obj:`int`, optional): Video duration in seconds.
|
||||
supports_streaming (:obj:`bool`, optional): Pass :obj:`True`, if the uploaded video is
|
||||
suitable for streaming.
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): Type of the media, always
|
||||
:tg-const:`telegram.constants.InputPaidMediaType.VIDEO`.
|
||||
media (:obj:`str` | :class:`telegram.InputFile`): Video to send.
|
||||
thumbnail (:class:`telegram.InputFile`): Optional. |thumbdocstringbase|
|
||||
width (:obj:`int`): Optional. Video width.
|
||||
height (:obj:`int`): Optional. Video height.
|
||||
duration (:obj:`int`): Optional. Video duration in seconds.
|
||||
supports_streaming (:obj:`bool`): Optional. :obj:`True`, if the uploaded video is
|
||||
suitable for streaming.
|
||||
"""
|
||||
|
||||
__slots__ = ("duration", "height", "supports_streaming", "thumbnail", "width")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
media: Union[FileInput, Video],
|
||||
thumbnail: Optional[FileInput] = None,
|
||||
width: Optional[int] = None,
|
||||
height: Optional[int] = None,
|
||||
duration: Optional[int] = None,
|
||||
supports_streaming: Optional[bool] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
if isinstance(media, Video):
|
||||
width = width if width is not None else media.width
|
||||
height = height if height is not None else media.height
|
||||
duration = duration if duration is not None else media.duration
|
||||
media = media.file_id
|
||||
else:
|
||||
# We use local_mode=True because we don't have access to the actual setting and want
|
||||
# things to work in local mode.
|
||||
media = parse_file_input(media, attach=True, local_mode=True)
|
||||
|
||||
super().__init__(type=InputPaidMedia.VIDEO, media=media, api_kwargs=api_kwargs)
|
||||
with self._unfrozen():
|
||||
self.thumbnail: Optional[Union[str, InputFile]] = InputMedia._parse_thumbnail_input(
|
||||
thumbnail
|
||||
)
|
||||
self.width: Optional[int] = width
|
||||
self.height: Optional[int] = height
|
||||
self.duration: Optional[int] = duration
|
||||
self.supports_streaming: Optional[bool] = supports_streaming
|
||||
|
||||
|
||||
class InputMediaAnimation(InputMedia):
|
||||
"""Represents an animation file (GIF or H.264/MPEG-4 AVC video without sound) to be sent.
|
||||
|
||||
Note:
|
||||
When using a :class:`telegram.Animation` for the :attr:`media` attribute, it will take the
|
||||
width, height and duration from that video, unless otherwise specified with the optional
|
||||
arguments.
|
||||
width, height and duration from that animation, unless otherwise specified with the
|
||||
optional arguments.
|
||||
|
||||
.. seealso:: :wiki:`Working with Files and Media <Working-with-Files-and-Media>`
|
||||
|
||||
@@ -129,8 +279,8 @@ class InputMediaAnimation(InputMedia):
|
||||
|removed_thumb_note|
|
||||
|
||||
Args:
|
||||
media (:obj:`str` | :term:`file object` | :obj:`bytes` | :class:`pathlib.Path` | \
|
||||
:class:`telegram.Animation`): File to send. |fileinputnopath|
|
||||
media (:obj:`str` | :term:`file object` | :class:`~telegram.InputFile` | :obj:`bytes` | \
|
||||
:class:`pathlib.Path` | :class:`telegram.Animation`): File to send. |fileinputnopath|
|
||||
Lastly you can pass an existing :class:`telegram.Animation` object to send.
|
||||
|
||||
.. versionchanged:: 13.2
|
||||
@@ -252,8 +402,8 @@ class InputMediaPhoto(InputMedia):
|
||||
.. seealso:: :wiki:`Working with Files and Media <Working-with-Files-and-Media>`
|
||||
|
||||
Args:
|
||||
media (:obj:`str` | :term:`file object` | :obj:`bytes` | :class:`pathlib.Path` | \
|
||||
:class:`telegram.PhotoSize`): File to send. |fileinputnopath|
|
||||
media (:obj:`str` | :term:`file object` | :class:`~telegram.InputFile` | :obj:`bytes` | \
|
||||
:class:`pathlib.Path` | :class:`telegram.PhotoSize`): File to send. |fileinputnopath|
|
||||
Lastly you can pass an existing :class:`telegram.PhotoSize` object to send.
|
||||
|
||||
.. versionchanged:: 13.2
|
||||
@@ -352,8 +502,8 @@ class InputMediaVideo(InputMedia):
|
||||
|removed_thumb_note|
|
||||
|
||||
Args:
|
||||
media (:obj:`str` | :term:`file object` | :obj:`bytes` | :class:`pathlib.Path` | \
|
||||
:class:`telegram.Video`): File to send. |fileinputnopath|
|
||||
media (:obj:`str` | :term:`file object` | :class:`~telegram.InputFile` | :obj:`bytes` | \
|
||||
:class:`pathlib.Path` | :class:`telegram.Video`): File to send. |fileinputnopath|
|
||||
Lastly you can pass an existing :class:`telegram.Video` object to send.
|
||||
|
||||
.. versionchanged:: 13.2
|
||||
@@ -490,8 +640,8 @@ class InputMediaAudio(InputMedia):
|
||||
|removed_thumb_note|
|
||||
|
||||
Args:
|
||||
media (:obj:`str` | :term:`file object` | :obj:`bytes` | :class:`pathlib.Path` | \
|
||||
:class:`telegram.Audio`): File to send. |fileinputnopath|
|
||||
media (:obj:`str` | :term:`file object` | :class:`~telegram.InputFile` | :obj:`bytes` | \
|
||||
:class:`pathlib.Path` | :class:`telegram.Audio`): File to send. |fileinputnopath|
|
||||
Lastly you can pass an existing :class:`telegram.Audio` object to send.
|
||||
|
||||
.. versionchanged:: 13.2
|
||||
@@ -510,10 +660,10 @@ class InputMediaAudio(InputMedia):
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceclassargs|
|
||||
|
||||
duration (:obj:`int`, optional): Duration of the audio in seconds as defined by sender.
|
||||
performer (:obj:`str`, optional): Performer of the audio as defined by sender or by audio
|
||||
tags.
|
||||
title (:obj:`str`, optional): Title of the audio as defined by sender or by audio tags.
|
||||
duration (:obj:`int`, optional): Duration of the audio in seconds as defined by the sender.
|
||||
performer (:obj:`str`, optional): Performer of the audio as defined by the sender or by
|
||||
audio tags.
|
||||
title (:obj:`str`, optional): Title of the audio as defined by the sender or by audio tags.
|
||||
thumbnail (:term:`file object` | :obj:`bytes` | :class:`pathlib.Path` | :obj:`str`, \
|
||||
optional): |thumbdocstringnopath|
|
||||
|
||||
@@ -533,9 +683,9 @@ class InputMediaAudio(InputMedia):
|
||||
* |tupleclassattrs|
|
||||
* |alwaystuple|
|
||||
duration (:obj:`int`): Optional. Duration of the audio in seconds.
|
||||
performer (:obj:`str`): Optional. Performer of the audio as defined by sender or by audio
|
||||
tags.
|
||||
title (:obj:`str`): Optional. Title of the audio as defined by sender or by audio tags.
|
||||
performer (:obj:`str`): Optional. Performer of the audio as defined by the sender or by
|
||||
audio tags.
|
||||
title (:obj:`str`): Optional. Title of the audio as defined by the sender or by audio tags.
|
||||
thumbnail (:class:`telegram.InputFile`): Optional. |thumbdocstringbase|
|
||||
|
||||
.. versionadded:: 20.2
|
||||
@@ -594,8 +744,8 @@ class InputMediaDocument(InputMedia):
|
||||
|removed_thumb_note|
|
||||
|
||||
Args:
|
||||
media (:obj:`str` | :term:`file object` | :obj:`bytes` | :class:`pathlib.Path` | \
|
||||
:class:`telegram.Document`): File to send. |fileinputnopath|
|
||||
media (:obj:`str` | :term:`file object` | :class:`~telegram.InputFile` | :obj:`bytes` \
|
||||
| :class:`pathlib.Path` | :class:`telegram.Document`): File to send. |fileinputnopath|
|
||||
Lastly you can pass an existing :class:`telegram.Document` object to send.
|
||||
|
||||
.. versionchanged:: 13.2
|
||||
|
||||
@@ -41,14 +41,15 @@ class InputSticker(TelegramObject):
|
||||
order of the arguments has changed.
|
||||
|
||||
Args:
|
||||
sticker (:obj:`str` | :term:`file object` | :obj:`bytes` | :class:`pathlib.Path`): The
|
||||
sticker (:obj:`str` | :term:`file object` | :class:`~telegram.InputFile` | :obj:`bytes` \
|
||||
| :class:`pathlib.Path`): The
|
||||
added sticker. |uploadinputnopath| Animated and video stickers can't be uploaded via
|
||||
HTTP URL.
|
||||
emoji_list (Sequence[:obj:`str`]): Sequence of
|
||||
:tg-const:`telegram.constants.StickerLimit.MIN_STICKER_EMOJI` -
|
||||
:tg-const:`telegram.constants.StickerLimit.MAX_STICKER_EMOJI` emoji associated with the
|
||||
sticker.
|
||||
mask_position (:obj:`telegram.MaskPosition`, optional): Position where the mask should be
|
||||
mask_position (:class:`telegram.MaskPosition`, optional): Position where the mask should be
|
||||
placed on faces. For ":tg-const:`telegram.constants.StickerType.MASK`" stickers only.
|
||||
keywords (Sequence[:obj:`str`], optional): Sequence of
|
||||
0-:tg-const:`telegram.constants.StickerLimit.MAX_SEARCH_KEYWORDS` search keywords
|
||||
@@ -70,7 +71,7 @@ class InputSticker(TelegramObject):
|
||||
:tg-const:`telegram.constants.StickerLimit.MIN_STICKER_EMOJI` -
|
||||
:tg-const:`telegram.constants.StickerLimit.MAX_STICKER_EMOJI` emoji associated with the
|
||||
sticker.
|
||||
mask_position (:obj:`telegram.MaskPosition`): Optional. Position where the mask should be
|
||||
mask_position (:class:`telegram.MaskPosition`): Optional. Position where the mask should be
|
||||
placed on faces. For ":tg-const:`telegram.constants.StickerType.MASK`" stickers only.
|
||||
keywords (Tuple[:obj:`str`]): Optional. Tuple of
|
||||
0-:tg-const:`telegram.constants.StickerLimit.MAX_SEARCH_KEYWORDS` search keywords
|
||||
|
||||
@@ -32,8 +32,8 @@ class Location(TelegramObject):
|
||||
considered equal, if their :attr:`longitude` and :attr:`latitude` are equal.
|
||||
|
||||
Args:
|
||||
longitude (:obj:`float`): Longitude as defined by sender.
|
||||
latitude (:obj:`float`): Latitude as defined by sender.
|
||||
longitude (:obj:`float`): Longitude as defined by the sender.
|
||||
latitude (:obj:`float`): Latitude as defined by the sender.
|
||||
horizontal_accuracy (:obj:`float`, optional): The radius of uncertainty for the location,
|
||||
measured in meters; 0-:tg-const:`telegram.Location.HORIZONTAL_ACCURACY`.
|
||||
live_period (:obj:`int`, optional): Time relative to the message sending date, during which
|
||||
@@ -45,8 +45,8 @@ class Location(TelegramObject):
|
||||
approaching another chat member, in meters. For sent live locations only.
|
||||
|
||||
Attributes:
|
||||
longitude (:obj:`float`): Longitude as defined by sender.
|
||||
latitude (:obj:`float`): Latitude as defined by sender.
|
||||
longitude (:obj:`float`): Longitude as defined by the sender.
|
||||
latitude (:obj:`float`): Latitude as defined by the sender.
|
||||
horizontal_accuracy (:obj:`float`): Optional. The radius of uncertainty for the location,
|
||||
measured in meters; 0-:tg-const:`telegram.Location.HORIZONTAL_ACCURACY`.
|
||||
live_period (:obj:`int`): Optional. Time relative to the message sending date, during which
|
||||
|
||||
@@ -193,7 +193,7 @@ class Sticker(_BaseThumbedMedium):
|
||||
""":const:`telegram.constants.StickerType.CUSTOM_EMOJI`"""
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["Sticker"]:
|
||||
def de_json(cls, data: Optional[JSONDict], bot: Optional["Bot"] = None) -> Optional["Sticker"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
@@ -305,7 +305,9 @@ class StickerSet(TelegramObject):
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["StickerSet"]:
|
||||
def de_json(
|
||||
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
|
||||
) -> Optional["StickerSet"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
if not data:
|
||||
return None
|
||||
|
||||
@@ -103,7 +103,7 @@ class Venue(TelegramObject):
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["Venue"]:
|
||||
def de_json(cls, data: Optional[JSONDict], bot: Optional["Bot"] = None) -> Optional["Venue"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
|
||||
+10
-10
@@ -39,11 +39,11 @@ class Video(_BaseThumbedMedium):
|
||||
file_unique_id (:obj:`str`): Unique identifier for this file, which
|
||||
is supposed to be the same over time and for different bots.
|
||||
Can't be used to download or reuse the file.
|
||||
width (:obj:`int`): Video width as defined by sender.
|
||||
height (:obj:`int`): Video height as defined by sender.
|
||||
duration (:obj:`int`): Duration of the video in seconds as defined by sender.
|
||||
file_name (:obj:`str`, optional): Original filename as defined by sender.
|
||||
mime_type (:obj:`str`, optional): MIME type of a file as defined by sender.
|
||||
width (:obj:`int`): Video width as defined by the sender.
|
||||
height (:obj:`int`): Video height as defined by the sender.
|
||||
duration (:obj:`int`): Duration of the video in seconds as defined by the sender.
|
||||
file_name (:obj:`str`, optional): Original filename as defined by the sender.
|
||||
mime_type (:obj:`str`, optional): MIME type of a file as defined by the sender.
|
||||
file_size (:obj:`int`, optional): File size in bytes.
|
||||
thumbnail (:class:`telegram.PhotoSize`, optional): Video thumbnail.
|
||||
|
||||
@@ -55,11 +55,11 @@ class Video(_BaseThumbedMedium):
|
||||
file_unique_id (:obj:`str`): Unique identifier for this file, which
|
||||
is supposed to be the same over time and for different bots.
|
||||
Can't be used to download or reuse the file.
|
||||
width (:obj:`int`): Video width as defined by sender.
|
||||
height (:obj:`int`): Video height as defined by sender.
|
||||
duration (:obj:`int`): Duration of the video in seconds as defined by sender.
|
||||
file_name (:obj:`str`): Optional. Original filename as defined by sender.
|
||||
mime_type (:obj:`str`): Optional. MIME type of a file as defined by sender.
|
||||
width (:obj:`int`): Video width as defined by the sender.
|
||||
height (:obj:`int`): Video height as defined by the sender.
|
||||
duration (:obj:`int`): Duration of the video in seconds as defined by the sender.
|
||||
file_name (:obj:`str`): Optional. Original filename as defined by the sender.
|
||||
mime_type (:obj:`str`): Optional. MIME type of a file as defined by the sender.
|
||||
file_size (:obj:`int`): Optional. File size in bytes.
|
||||
thumbnail (:class:`telegram.PhotoSize`): Optional. Video thumbnail.
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ class VideoNote(_BaseThumbedMedium):
|
||||
Can't be used to download or reuse the file.
|
||||
length (:obj:`int`): Video width and height (diameter of the video message) as defined
|
||||
by sender.
|
||||
duration (:obj:`int`): Duration of the video in seconds as defined by sender.
|
||||
duration (:obj:`int`): Duration of the video in seconds as defined by the sender.
|
||||
file_size (:obj:`int`, optional): File size in bytes.
|
||||
thumbnail (:class:`telegram.PhotoSize`, optional): Video thumbnail.
|
||||
|
||||
@@ -56,7 +56,7 @@ class VideoNote(_BaseThumbedMedium):
|
||||
Can't be used to download or reuse the file.
|
||||
length (:obj:`int`): Video width and height (diameter of the video message) as defined
|
||||
by sender.
|
||||
duration (:obj:`int`): Duration of the video in seconds as defined by sender.
|
||||
duration (:obj:`int`): Duration of the video in seconds as defined by the sender.
|
||||
file_size (:obj:`int`): Optional. File size in bytes.
|
||||
thumbnail (:class:`telegram.PhotoSize`): Optional. Video thumbnail.
|
||||
|
||||
|
||||
@@ -35,8 +35,8 @@ class Voice(_BaseMedium):
|
||||
file_unique_id (:obj:`str`): Unique identifier for this file, which
|
||||
is supposed to be the same over time and for different bots.
|
||||
Can't be used to download or reuse the file.
|
||||
duration (:obj:`int`): Duration of the audio in seconds as defined by sender.
|
||||
mime_type (:obj:`str`, optional): MIME type of the file as defined by sender.
|
||||
duration (:obj:`int`): Duration of the audio in seconds as defined by the sender.
|
||||
mime_type (:obj:`str`, optional): MIME type of the file as defined by the sender.
|
||||
file_size (:obj:`int`, optional): File size in bytes.
|
||||
|
||||
Attributes:
|
||||
@@ -45,8 +45,8 @@ class Voice(_BaseMedium):
|
||||
file_unique_id (:obj:`str`): Unique identifier for this file, which
|
||||
is supposed to be the same over time and for different bots.
|
||||
Can't be used to download or reuse the file.
|
||||
duration (:obj:`int`): Duration of the audio in seconds as defined by sender.
|
||||
mime_type (:obj:`str`): Optional. MIME type of the file as defined by sender.
|
||||
duration (:obj:`int`): Duration of the audio in seconds as defined by the sender.
|
||||
mime_type (:obj:`str`): Optional. MIME type of the file as defined by the sender.
|
||||
file_size (:obj:`int`): Optional. File size in bytes.
|
||||
|
||||
"""
|
||||
|
||||
@@ -24,6 +24,7 @@ from telegram._files.photosize import PhotoSize
|
||||
from telegram._messageentity import MessageEntity
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||
from telegram._utils.strings import TextEncoding
|
||||
from telegram._utils.types import JSONDict
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@@ -122,7 +123,7 @@ class Game(TelegramObject):
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["Game"]:
|
||||
def de_json(cls, data: Optional[JSONDict], bot: Optional["Bot"] = None) -> Optional["Game"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
@@ -157,10 +158,10 @@ class Game(TelegramObject):
|
||||
if not self.text:
|
||||
raise RuntimeError("This Game has no 'text'.")
|
||||
|
||||
entity_text = self.text.encode("utf-16-le")
|
||||
entity_text = self.text.encode(TextEncoding.UTF_16_LE)
|
||||
entity_text = entity_text[entity.offset * 2 : (entity.offset + entity.length) * 2]
|
||||
|
||||
return entity_text.decode("utf-16-le")
|
||||
return entity_text.decode(TextEncoding.UTF_16_LE)
|
||||
|
||||
def parse_text_entities(self, types: Optional[List[str]] = None) -> Dict[MessageEntity, str]:
|
||||
"""
|
||||
|
||||
@@ -61,7 +61,9 @@ class GameHighScore(TelegramObject):
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["GameHighScore"]:
|
||||
def de_json(
|
||||
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
|
||||
) -> Optional["GameHighScore"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
|
||||
+13
-7
@@ -123,8 +123,10 @@ class Giveaway(TelegramObject):
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["Giveaway"]:
|
||||
"""See :obj:`telegram.TelegramObject.de_json`."""
|
||||
def de_json(
|
||||
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
|
||||
) -> Optional["Giveaway"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
if data is None:
|
||||
@@ -257,8 +259,10 @@ class GiveawayWinners(TelegramObject):
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["GiveawayWinners"]:
|
||||
"""See :obj:`telegram.TelegramObject.de_json`."""
|
||||
def de_json(
|
||||
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
|
||||
) -> Optional["GiveawayWinners"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
if data is None:
|
||||
@@ -313,7 +317,7 @@ class GiveawayCompleted(TelegramObject):
|
||||
|
||||
self.winner_count: int = winner_count
|
||||
self.unclaimed_prize_count: Optional[int] = unclaimed_prize_count
|
||||
self.giveaway_message: Optional["Message"] = giveaway_message
|
||||
self.giveaway_message: Optional[Message] = giveaway_message
|
||||
|
||||
self._id_attrs = (
|
||||
self.winner_count,
|
||||
@@ -323,8 +327,10 @@ class GiveawayCompleted(TelegramObject):
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["GiveawayCompleted"]:
|
||||
"""See :obj:`telegram.TelegramObject.de_json`."""
|
||||
def de_json(
|
||||
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
|
||||
) -> Optional["GiveawayCompleted"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
if data is None:
|
||||
|
||||
@@ -46,7 +46,7 @@ class InlineKeyboardButton(TelegramObject):
|
||||
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
|
||||
from telegram, :attr:`callback_data` maybe be an instance of
|
||||
from telegram, :attr:`callback_data` may be an instance of
|
||||
:class:`telegram.ext.InvalidCallbackData`. This will be the case, if the data
|
||||
associated with the button was already deleted.
|
||||
|
||||
@@ -89,10 +89,9 @@ class InlineKeyboardButton(TelegramObject):
|
||||
Caution:
|
||||
Only ``HTTPS`` links are allowed after Bot API 6.1.
|
||||
callback_data (:obj:`str` | :obj:`object`, optional): Data to be sent in a callback query
|
||||
to the bot when button is pressed, UTF-8
|
||||
to the bot when the 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:
|
||||
@@ -100,7 +99,7 @@ class InlineKeyboardButton(TelegramObject):
|
||||
|
||||
.. seealso:: :wiki:`Arbitrary callback_data <Arbitrary-callback_data>`
|
||||
|
||||
web_app (:obj:`telegram.WebAppInfo`, optional): Description of the `Web App
|
||||
web_app (:class:`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
|
||||
@@ -108,21 +107,22 @@ class InlineKeyboardButton(TelegramObject):
|
||||
a Telegram Business account.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
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.
|
||||
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. May be empty, in which case just the bot's
|
||||
username will be inserted. Not supported for messages sent on behalf of a Telegram
|
||||
Business account.
|
||||
|
||||
Tip:
|
||||
This is similar to the new parameter :paramref:`switch_inline_query_chosen_chat`,
|
||||
This is similar to the 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
|
||||
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.
|
||||
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.
|
||||
callback_game (:class:`telegram.CallbackGame`, optional): Description of the game that will
|
||||
be launched when the user presses the button
|
||||
|
||||
@@ -135,7 +135,7 @@ class InlineKeyboardButton(TelegramObject):
|
||||
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):
|
||||
switch_inline_query_chosen_chat (:class:`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. Not supported for messages sent on behalf of a Telegram
|
||||
@@ -165,11 +165,10 @@ class InlineKeyboardButton(TelegramObject):
|
||||
Caution:
|
||||
Only ``HTTPS`` links are allowed after Bot API 6.1.
|
||||
callback_data (:obj:`str` | :obj:`object`): Optional. Data to be sent in a callback query
|
||||
to the bot when button is pressed, UTF-8
|
||||
to the bot when the 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
|
||||
web_app (:class:`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
|
||||
@@ -177,21 +176,22 @@ class InlineKeyboardButton(TelegramObject):
|
||||
a Telegram Business account.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
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.
|
||||
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. May be empty, in which case just the bot's
|
||||
username will be inserted. Not supported for messages sent on behalf of a Telegram
|
||||
Business account.
|
||||
|
||||
Tip:
|
||||
This is similar to the new parameter :paramref:`switch_inline_query_chosen_chat`,
|
||||
This is similar to the 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
|
||||
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.
|
||||
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.
|
||||
callback_game (:class:`telegram.CallbackGame`): Optional. Description of the game that will
|
||||
be launched when the user presses the button.
|
||||
|
||||
@@ -204,7 +204,7 @@ class InlineKeyboardButton(TelegramObject):
|
||||
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.
|
||||
switch_inline_query_chosen_chat (:class:`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. Not supported for messages sent on behalf of a Telegram
|
||||
@@ -284,7 +284,9 @@ class InlineKeyboardButton(TelegramObject):
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["InlineKeyboardButton"]:
|
||||
def de_json(
|
||||
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
|
||||
) -> Optional["InlineKeyboardButton"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ class InlineKeyboardMarkup(TelegramObject):
|
||||
An inline keyboard on a message
|
||||
|
||||
.. seealso::
|
||||
An another kind of keyboard would be the :class:`telegram.ReplyKeyboardMarkup`.
|
||||
Another kind of keyboard would be the :class:`telegram.ReplyKeyboardMarkup`.
|
||||
|
||||
Examples:
|
||||
* :any:`Inline Keyboard 1 <examples.inlinekeyboard>`
|
||||
@@ -90,7 +90,9 @@ class InlineKeyboardMarkup(TelegramObject):
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["InlineKeyboardMarkup"]:
|
||||
def de_json(
|
||||
cls, data: Optional[JSONDict], bot: Optional["Bot"] = None
|
||||
) -> Optional["InlineKeyboardMarkup"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
if not data:
|
||||
return None
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user