Compare commits

..

29 Commits

Author SHA1 Message Date
Bibo-Joshi 0748538b6f Bump Version to v22.4 (#4939) 2025-09-13 17:14:30 +02:00
Bibo-Joshi 539cc13097 Documentation Improvements (#4878)
Co-authored-by: Ca5parAD <github.unearned388@passmail.net>
Co-authored-by: Harshil <37377066+harshil21@users.noreply.github.com>
Co-authored-by: Poolitzer <github@poolitzer.eu>
Co-authored-by: aelkheir <90580077+aelkheir@users.noreply.github.com>
2025-09-13 16:56:58 +02:00
Abdelrahman Elkheir 068ee7ea9d Full Support for Bot API 9.2 (#4911)
Co-authored-by: Harshil <37377066+harshil21@users.noreply.github.com>
Co-authored-by: Poolitzer <github@poolitzer.eu>
Co-authored-by: Hinrich Mahler <22366557+Bibo-Joshi@users.noreply.github.com>
2025-09-13 16:56:04 +02:00
renovate[bot] 73e5958ee6 Replace Dependabot with Renovate (#4887)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Harshil <37377066+harshil21@users.noreply.github.com>
Co-authored-by: Hinrich Mahler <22366557+Bibo-Joshi@users.noreply.github.com>
2025-09-10 16:13:34 +02:00
Jãїиãм 0790bd8364 Support Business Message Deletion in telegram.Message.delete() (#4869)
Co-authored-by: aelkheir <90580077+aelkheir@users.noreply.github.com>
2025-09-07 20:50:27 +02:00
Harshil 9205d01edc Use Tagged Release of pydantic in Development Dependencies (#4934)
Co-authored-by: Bibo-Joshi <22366557+Bibo-Joshi@users.noreply.github.com>
2025-09-07 20:25:22 +02:00
dependabot[bot] 55241e4aed Bump pytest from 8.4.1 to 8.4.2 (#4933)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Bibo-Joshi <22366557+Bibo-Joshi@users.noreply.github.com>
2025-09-06 04:14:44 +02:00
dependabot[bot] 4a0fb4d533 Update cachetools requirement from <6.2.0,>=5.3.3 to >=5.3.3,<6.3.0 (#4923)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Bibo-Joshi <22366557+Bibo-Joshi@users.noreply.github.com>
2025-09-05 20:27:09 +02:00
dependabot[bot] 3e82dd4afd Bump actions/checkout from 4.2.2 to 5.0.0 (#4925)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Bibo-Joshi <22366557+Bibo-Joshi@users.noreply.github.com>
2025-09-05 20:26:24 +02:00
dependabot[bot] aa11132358 Bump codecov/codecov-action from 5.4.3 to 5.5.0 (#4926)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Bibo-Joshi <22366557+Bibo-Joshi@users.noreply.github.com>
2025-09-05 20:26:08 +02:00
dependabot[bot] 646730eed1 Bump github/codeql-action from 3.29.7 to 3.30.0 (#4929)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Bibo-Joshi <22366557+Bibo-Joshi@users.noreply.github.com>
2025-09-05 20:25:47 +02:00
dependabot[bot] 08385e27db Bump actions/download-artifact from 4.3.0 to 5.0.0 (#4927)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Bibo-Joshi <22366557+Bibo-Joshi@users.noreply.github.com>
2025-09-05 20:25:21 +02:00
dependabot[bot] 8bb5c93c09 Bump astral-sh/setup-uv from 6.4.3 to 6.6.1 (#4928)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Bibo-Joshi <22366557+Bibo-Joshi@users.noreply.github.com>
2025-09-05 20:25:02 +02:00
Harshil 1472674587 Don't update uv.lock in copilot runtime environment (#4915) 2025-08-17 11:36:03 +02:00
Copilot 19d891aceb Fix ResourceWarning when passing pathlib.Path to methods which accept file input (#4908)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: harshil21 <37377066+harshil21@users.noreply.github.com>
2025-08-17 11:34:01 +02:00
Harshil 47fd9fcc7e Add filters.FORUM (#4906) 2025-08-17 11:20:02 +02:00
Harshil 4654d195f5 Add GitHub Copilot Instructions and Setup Steps (#4884) 2025-08-08 06:53:48 +02:00
Harshil 58390dd350 Add uv.lock (#4890)
Co-authored-by: Bibo-Joshi <22366557+Bibo-Joshi@users.noreply.github.com>
2025-08-08 06:53:03 +02:00
Copilot cea812dabd Adapt Logic on Getting the Event Loop in Application.run_polling/webhook to Python 3.14 (#4875)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: harshil21 <37377066+harshil21@users.noreply.github.com>
2025-08-02 17:18:53 +02:00
dependabot[bot] 94da8a8d67 Bump pytest-xdist from 3.6.1 to 3.8.0 (#4893)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Bibo-Joshi <22366557+Bibo-Joshi@users.noreply.github.com>
2025-08-02 03:54:46 +02:00
dependabot[bot] 616cfe59b9 Bump furo from 2024.8.6 to 2025.7.19 (#4894)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Bibo-Joshi <22366557+Bibo-Joshi@users.noreply.github.com>
2025-08-02 03:30:29 +02:00
dependabot[bot] aeb4b58fa1 Bump pytest from 8.4.0 to 8.4.1 (#4892)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Bibo-Joshi <22366557+Bibo-Joshi@users.noreply.github.com>
2025-08-02 03:18:46 +02:00
dependabot[bot] 4196a3d787 Bump astral-sh/setup-uv from 6.3.1 to 6.4.3 (#4895)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Bibo-Joshi <22366557+Bibo-Joshi@users.noreply.github.com>
2025-08-02 03:06:03 +02:00
dependabot[bot] 7e75469697 Bump github/codeql-action from 3.29.2 to 3.29.5 (#4896)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Bibo-Joshi <22366557+Bibo-Joshi@users.noreply.github.com>
2025-08-02 03:05:47 +02:00
Bibo-Joshi a76fa2c79e Improve Internal Logic for Network Retries (#4880) 2025-08-02 02:11:57 +02:00
Poolitzer 197f29b6eb Improve HTTPXRequest Connection Pool Settings (#4882)
Co-authored-by: Harshil <37377066+harshil21@users.noreply.github.com>
Co-authored-by: Bibo-Joshi <22366557+Bibo-Joshi@users.noreply.github.com>
2025-07-31 20:54:35 +02:00
Harshil 89dd168ab2 Remove black, isort, flake8, and pyupgrade in favor of Ruff (#4886) 2025-07-31 19:25:36 +02:00
Abdelrahman Elkheir 6752547460 Add Convenience Properties to SharedUser and ChatShared (#4881)
Co-authored-by: david-shiko <dsb321mp@gmail.com>
2025-07-28 18:34:01 +02:00
Bibo-Joshi 996b0b3025 Address Failing Unit Test for send_paid_media (#4879) 2025-07-26 17:23:27 +02:00
275 changed files with 6662 additions and 536 deletions
+2 -3
View File
@@ -87,7 +87,7 @@ Here's how to make a one-off code change.
- Documenting types of global variables and complex types of class members can be done using the Sphinx docstring convention.
- In addition, PTB uses some formatting/styling and linting tools in the pre-commit setup. Some of those tools also have command line tools that can help to run these tools outside of the pre-commit step. If you'd like to leverage that, please have a look at the `pre-commit config file`_ for an overview of which tools (and which versions of them) are used. For example, we use `Black`_ for code formatting. Plugins for Black exist for some `popular editors`_. You can use those instead of manually formatting everything.
- In addition, PTB uses some formatting/styling and linting tools in the pre-commit setup. Some of those tools also have command line tools that can help to run these tools outside of the pre-commit step. If you'd like to leverage that, please have a look at the `pre-commit config file`_ for an overview of which tools (and which versions of them) are used. For example, we use `Ruff`_ for linting and formatting.
- Please ensure that the code you write is well-tested and that all automated tests still pass. We
have dedicated an `testing page`_ to help you with that.
@@ -288,8 +288,7 @@ to add new required arguments. It's also more explicit and easier to read.
.. _`MyPy`: https://mypy.readthedocs.io/en/stable/index.html
.. _`here`: https://mypy.readthedocs.io/en/stable/cheat_sheet_py3.html
.. _`pre-commit config file`: https://github.com/python-telegram-bot/python-telegram-bot/blob/master/.pre-commit-config.yaml
.. _`Black`: https://black.readthedocs.io/en/stable/index.html
.. _`popular editors`: https://black.readthedocs.io/en/stable/integrations/editors.html
.. _`Ruff`: https://docs.astral.sh/ruff/
.. _`RTD`: https://docs.python-telegram-bot.org/
.. _`RTD build`: https://docs.python-telegram-bot.org/en/doc-fixes
.. _`CSI`: https://standards.mousepawmedia.com/en/stable/csi.html
+40
View File
@@ -0,0 +1,40 @@
This is a python project which is a wrapper for the Telegram Bot API. Please read the contributing
guidelines mentioned in .github/CONTRIBUTING.rst to know how to contribute to this project. The
README.rst file lists the features and usage of the project.
### Development Environment:
Your development environment is set up using `uv`, a tool for managing Python environments and dependencies.
Your environment has all extra dependencies and groups installed, on Python 3.13. Please continue using `uv` for managing your development environment,
and for any scripts or tools you need to run.
Some example commands on `uv`:
- `uv sync --all-extras --all-groups --locked` to install all dependencies and groups required by the project.
- `uv run -p 3.14 --all-groups --all-extras --locked tests/` to run tests on a specific Python version. Please use the `-p` flag often.
- `uv pip install <package>` to install a package in the current environment.
If uv is somehow not available, you can install it using `pip install uv`.
### Repository Structure:
The repository follows a standard structure for Python projects. Here are some key directories and files:
- `src/`: This directory contains the main source code for the project.
- `tests/`: This directory contains test cases for the project.
- `pyproject.toml`: This file contains the project metadata and dependencies.
- `.github/`: This directory contains GitHub-specific files, including workflows and issue templates.
### Things to keep in mind while coding:
- Ensure that your code is properly and fully typed. All your code should be compatible from
Python 3.9 to 3.14. Don't use the `typing_extensions` module.
- Read the stability guide mentioned at docs/source/stability_policy.rst to understand if your changes
are breaking or incompatible.
- Try to make sure your code is asyncio-friendly and thread-safe.
- Run `uv run pre-commit` to run pre-commit hooks before committing your changes, but after `git add`ing them.
- Make sure you always test your changes. Either update or write new tests in the `tests/` directory.
### Pull Requests:
When you create a pull request, please also add the appropriate labels to it.
-20
View File
@@ -1,20 +0,0 @@
version: 2
updates:
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "weekly"
day: "friday"
labels:
- "⚙️ dependencies"
- "🔗 python"
# Updates the dependencies of the GitHub Actions workflows
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "monthly"
day: "friday"
labels:
- "⚙️ dependencies"
- "🔗 github-actions"
+81
View File
@@ -0,0 +1,81 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [ // See what config:best-practices does: https://docs.renovatebot.com/presets-config/#configbest-practices
"config:best-practices",
// Opt-in to updating the pre-commit-config.yaml file too:
":enablePreCommit",
":prConcurrentLimitNone" // No limits on the number of open PRs.
],
// Add pull request labels:
"labels": ["dependencies"],
// Bump even patch versions:
"bumpVersion": "patch",
// Let Renovate decide how to update. See docs: https://docs.renovatebot.com/configuration-options/#rangestrategy
"rangeStrategy": "auto",
// Update the lock files:
"lockFileMaintenance": {
"enabled": true,
"schedule": ["* * * * 1,4"] // Run sometime on Monday and Thursday
},
// Bump the versions even in other files:
"bumpVersions": [
{
"name": "Update dependency versions in README.rst",
"filePatterns": ["README.rst"],
"matchStrings": [
"cryptography>=(?<version>\\d+\\.\\d+\\.\\d+)",
"aiolimiter~=(?<version>\\d+\\.\\d+\\.\\d+)",
"tornado~=(?<version>\\d+\\.\\d+)",
"cachetools>=(?<version>\\d+\\.\\d+\\.\\d+)", // Lower bound only
"APScheduler>=(?<version>\\d+\\.\\d+\\.\\d+)" // Lower bound only
],
"bumpType": "minor"
}
],
// Group package updates together:
"packageRules": [
// Linting dependencies in pyproject.toml in sync with the pre-commit-config hooks:
// Unfortunately it seems we need to do this for every dependency group (https://github.com/python-telegram-bot/python-telegram-bot/pull/4887#discussion_r2272025832):
{
"description": "Group Ruff updates together",
"matchPackageNames": ["ruff", "astral-sh/ruff-pre-commit"],
"groupName": "Ruff"
},
{
"description": "Group mypy updates together",
"matchPackageNames": ["mypy", "pre-commit/mirrors-mypy"],
"groupName": "Mypy"
},
{
"description": "Group pylint updates together",
"matchPackageNames": ["pylint", "PyCQA/pylint"],
"groupName": "Pylint"
},
{
"description": "Group chango updates together",
"matchPackageNames": ["chango", "Bibo-Joshi/chango"],
"groupName": "Chango"
},
// Automerge PR's for minor/patch/pin/digest (except major) updates:
{
"matchUpdateTypes": ["minor", "patch", "pin", "digest"],
"automerge": true
}
],
// Increase the number of PR's Renovate can create in a hour. Default is 2.
"prHourlyLimit": 5,
// Temporarily disabled:
"ignoreDeps": ["pytest-asyncio"],
// schedule to allow PR's from Renovate:
"schedule": ["* * * * 0,6"] // Every weekend
}
+2 -2
View File
@@ -20,7 +20,7 @@ jobs:
IS_RELEASE_PR: ${{ steps.check_title.outputs.IS_RELEASE_PR }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
# needed for commit and push step at the end
persist-credentials: true
@@ -36,7 +36,7 @@ jobs:
fi
# Create the new fragment
- uses: Bibo-Joshi/chango@9d6bd9d7612eca5fab2c5161687011be59baaf19 # v0.4.0
- uses: Bibo-Joshi/chango@9d6bd9d7612eca5fab2c5161687011be59baaf19 # 0.4.0
with:
github-token: ${{ secrets.CHANGO_PAT }}
query-issue-types: true
+42
View File
@@ -0,0 +1,42 @@
# This file is for the copilot agent on Github. This helps to set up the development environment
# See the docs here: https://docs.github.com/en/enterprise-cloud@latest/copilot/how-tos/use-copilot-agents/coding-agent/customize-the-agent-environment#preinstalling-tools-or-dependencies-in-copilots-environment
name: "Copilot Setup Steps"
# Automatically run the setup steps when they are changed to allow for easy validation, and
# allow manual testing through the repository's "Actions" tab
on:
workflow_dispatch:
pull_request:
paths:
- .github/workflows/copilot-setup-steps.yml
jobs:
# The job MUST be called `copilot-setup-steps` or it will not be picked up by Copilot.
copilot-setup-steps:
runs-on: ubuntu-latest
# Set the permissions to the lowest permissions possible needed for your steps.
# Copilot will be given its own token for its operations.
permissions:
# If you want to clone the repository as part of your setup steps, for example to install dependencies, you'll need the `contents: read` permission. If you don't clone the repository in your setup steps, Copilot will do this for you automatically after the steps complete.
contents: read
pull-requests: write # So copilot can add labels to the PR
# You can define any steps you want, and they will run before the agent starts.
# If you do not check out your code, Copilot will do this for you.
steps:
- name: Checkout code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
- name: Install uv
uses: astral-sh/setup-uv@557e51de59eb14aaaba2ed9621916900a91d50c6
with:
# Install a specific version of uv.
version: "0.8.3"
# Install 3.13:
python-version: 3.13
- name: Install the project
run: uv sync --all-extras --all-groups --locked
-41
View File
@@ -1,41 +0,0 @@
name: Process Dependabot PRs
on:
pull_request:
types: [opened, reopened]
permissions: {}
jobs:
process-dependabot-prs:
permissions:
pull-requests: read
contents: write
runs-on: ubuntu-latest
if: ${{ github.event.pull_request.user.login == 'dependabot[bot]' }}
steps:
- name: Fetch Dependabot metadata
id: dependabot-metadata
uses: dependabot/fetch-metadata@08eff52bf64351f401fb50d4972fa95b9f2c2d1b # v2.4.0
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ github.event.pull_request.head.ref }}
persist-credentials: false
- name: Update Version Number in Other Files
uses: jacobtomlinson/gha-find-replace@f1069b438f125e5395d84d1c6fd3b559a7880cb5 # v3
with:
find: ${{ steps.dependabot-metadata.outputs.previous-version }}
replace: ${{ steps.dependabot-metadata.outputs.new-version }}
regex: false
exclude: CHANGES.rst
- name: Commit & Push Changes to PR
uses: EndBug/add-and-commit@a94899bca583c204427a224a7af87c02f9b325d5 # v9.1.4
with:
message: 'Update version number in other files'
committer_name: GitHub Actions
committer_email: 41898282+github-actions[bot]@users.noreply.github.com
+1 -1
View File
@@ -24,7 +24,7 @@ jobs:
os: [ubuntu-latest]
fail-fast: False
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
- name: Set up Python ${{ matrix.python-version }}
+1 -1
View File
@@ -19,7 +19,7 @@ jobs:
os: [ubuntu-latest]
fail-fast: False
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
- name: Set up Python ${{ matrix.python-version }}
+4 -4
View File
@@ -17,17 +17,17 @@ jobs:
security-events: write
steps:
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
- name: Install the latest version of uv
uses: astral-sh/setup-uv@bd01e18f51369d5a26f1651c3cb451d3417e3bba # v6.3.1
uses: astral-sh/setup-uv@557e51de59eb14aaaba2ed9621916900a91d50c6 # v6.6.1
- name: Run zizmor
run: uvx zizmor --persona=pedantic --format sarif . > results.sarif
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload SARIF file
uses: github/codeql-action/upload-sarif@181d5eefc20863364f96762470ba6f862bdef56b # v3.29.2
uses: github/codeql-action/upload-sarif@2d92b76c45b91eb80fc44c74ce3fce0ee94e8f9d # v3.30.0
with:
sarif_file: results.sarif
category: zizmor
category: zizmor
+6 -6
View File
@@ -17,7 +17,7 @@ jobs:
actions: write
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
- name: Set up Python
@@ -55,7 +55,7 @@ jobs:
steps:
- name: Download all the dists
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
with:
name: python-package-distributions
path: dist/
@@ -74,7 +74,7 @@ jobs:
steps:
- name: Download all the dists
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
with:
name: python-package-distributions
path: dist/
@@ -110,11 +110,11 @@ jobs:
actions: read # for downloading artifacts
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
- name: Download all the dists
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
with:
name: python-package-distributions-and-signatures
path: dist/
@@ -155,7 +155,7 @@ jobs:
permissions: {}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
- name: Publish to Telegram Channel
+5 -5
View File
@@ -17,7 +17,7 @@ jobs:
actions: write
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
- name: Set up Python
@@ -55,7 +55,7 @@ jobs:
steps:
- name: Download all the dists
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
with:
name: python-package-distributions
path: dist/
@@ -76,7 +76,7 @@ jobs:
steps:
- name: Download all the dists
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
with:
name: python-package-distributions
path: dist/
@@ -112,11 +112,11 @@ jobs:
actions: read # for downloading artifacts
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
- name: Download all the dists
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
with:
name: python-package-distributions-and-signatures
path: dist/
+1 -1
View File
@@ -23,7 +23,7 @@ jobs:
os: [ubuntu-latest]
fail-fast: False
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
- name: Set up Python ${{ matrix.python-version }}
+1 -1
View File
@@ -16,7 +16,7 @@ jobs:
name: test-type-completeness
runs-on: ubuntu-latest
steps:
- uses: Bibo-Joshi/pyright-type-completeness@c85a67ff3c66f51dcbb2d06bfcf4fe83a57d69cc # v1.0.1
- uses: Bibo-Joshi/pyright-type-completeness@c85a67ff3c66f51dcbb2d06bfcf4fe83a57d69cc # 1.0.1
with:
package-name: telegram
python-version: 3.12
@@ -11,7 +11,7 @@ jobs:
name: test-type-completeness
runs-on: ubuntu-latest
steps:
- uses: Bibo-Joshi/pyright-type-completeness@c85a67ff3c66f51dcbb2d06bfcf4fe83a57d69cc # v1.0.1
- uses: Bibo-Joshi/pyright-type-completeness@c85a67ff3c66f51dcbb2d06bfcf4fe83a57d69cc # 1.0.1
id: pyright-type-completeness
with:
package-name: telegram
+2 -5
View File
@@ -9,9 +9,6 @@ on:
push:
branches:
- master
schedule:
# Run monday and friday morning at 03:07 - odd time to spread load on GitHub Actions
- cron: '7 3 * * 1,5'
permissions: {}
@@ -25,7 +22,7 @@ jobs:
os: [ubuntu-latest, windows-latest, macos-latest]
fail-fast: False
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
- name: Set up Python ${{ matrix.python-version }}
@@ -86,7 +83,7 @@ jobs:
.test_report_optionals_junit.xml
- name: Submit coverage
uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # v5.4.3
uses: codecov/codecov-action@fdcc8476540edceab3de004e990f80d881c6cc00 # v5.5.0
with:
env_vars: OS,PYTHON
name: ${{ matrix.os }}-${{ matrix.python-version }}
+4 -1
View File
@@ -97,4 +97,7 @@ pyvenv.cfg
Scripts/
# environment manager:
.mise.toml
.mise.toml
# Support for uv.lock will come in a future PR. See #4796
uv.lock
+13 -36
View File
@@ -1,38 +1,27 @@
# Make sure that the additional_dependencies here match pyproject.toml
ci:
autofix_prs: false
# We use Renovate to update this file now, but we can't disable automatic pre-commit updates
# when using the `pre-commit` GitHub Action, so we set the schedule to quarterly to avoid
# frequent updates.
autoupdate_schedule: quarterly
autoupdate_commit_msg: 'Bump `pre-commit` Hooks to Latest Versions'
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: 'v0.12.2'
rev: 'v0.12.7'
hooks:
- id: ruff
name: ruff
additional_dependencies:
- httpx~=0.27
- tornado~=6.4
- APScheduler~=3.10.4
- cachetools>=5.3.3,<5.5.0
- aiolimiter~=1.1,<1.3
- repo: https://github.com/psf/black-pre-commit-mirror
rev: 25.1.0
hooks:
- id: black
args:
- --diff
- --check
- repo: https://github.com/PyCQA/flake8
rev: 7.3.0
hooks:
- id: flake8
# Run the linter:
- id: ruff-check
name: ruff check
# Run the formatter:
- id: ruff-format
name: ruff format
- repo: https://github.com/PyCQA/pylint
rev: v3.3.7
hooks:
- id: pylint
files: ^(?!(tests|docs)).*\.py$
language: python
additional_dependencies:
- httpx~=0.27
- tornado~=6.4
@@ -46,6 +35,7 @@ repos:
- id: mypy
name: mypy-ptb
files: ^(?!(tests|examples|docs)).*\.py$
language: python
additional_dependencies:
- types-pytz
- types-cryptography
@@ -59,6 +49,7 @@ repos:
- id: mypy
name: mypy-examples
files: ^examples/.*\.py$
language: python
args:
- --no-strict-optional
- --follow-imports=silent
@@ -67,17 +58,3 @@ repos:
- APScheduler~=3.10.4
- cachetools>=5.3.3,<5.5.0
- . # this basically does `pip install -e .`
- repo: https://github.com/asottile/pyupgrade
rev: v3.20.0
hooks:
- id: pyupgrade
args:
- --py39-plus
- repo: https://github.com/pycqa/isort
rev: 6.0.1
hooks:
- id: isort
name: isort
args:
- --diff
- --check
+1 -1
View File
@@ -26,7 +26,7 @@ build:
jobs:
install:
- pip install -U pip
- pip install .[all] --group 'all' # install all the dependency groups
- pip install .[all] --group 'docs' --group 'tests' # install most dependency groups
post_build:
# Based on https://github.com/readthedocs/readthedocs.org/issues/3242#issuecomment-1410321534
+4 -4
View File
@@ -11,7 +11,7 @@
:target: https://pypi.org/project/python-telegram-bot/
:alt: Supported Python versions
.. image:: https://img.shields.io/badge/Bot%20API-9.1-blue?logo=telegram
.. image:: https://img.shields.io/badge/Bot%20API-9.2-blue?logo=telegram
:target: https://core.telegram.org/bots/api-changelog
:alt: Supported Bot API version
@@ -81,7 +81,7 @@ After installing_ the library, be sure to check out the section on `working with
Telegram API support
~~~~~~~~~~~~~~~~~~~~
All types and methods of the Telegram Bot API **9.1** are natively supported by this library.
All types and methods of the Telegram Bot API **9.2** 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
@@ -159,7 +159,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,<1.3 <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,<6.2.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[callback-data]"`` installs the `cachetools>=5.3.3,<6.3.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,<3.12.0 <https://apscheduler.readthedocs.io/en/3.x/>`_ library. 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]"``.
@@ -206,7 +206,7 @@ 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.
Because ``asyncio`` is in general single-threaded, ``python-telegram-bot`` currently does not aim to be thread-safe.
Noteworthy parts of ``python-telegram-bots`` API that are likely to cause issues (e.g. race conditions) when used in a multi-threaded setting include:
* ``telegram.ext.Application/Updater.update_queue``
@@ -0,0 +1,5 @@
features = "Extend :meth:`telegram.Message.delete` shortcut to support business message deletion"
[[pull_requests]]
uid = "4869"
author_uid = "jainamoswal"
closes_threads = ["4867"]
@@ -0,0 +1,5 @@
bugfixes = "Adapt logic on getting the event loop in ``Application.run_polling/webhook`` to Python 3.14"
[[pull_requests]]
uid = "4875"
author_uid = "harshil21"
closes_threads = ["4874"]
@@ -0,0 +1,9 @@
documentation = "Documentation Improvements"
[[pull_requests]]
uid = "4878"
author_uid = "Bibo-Joshi"
[[pull_requests]]
uid = "4872"
author_uid = "Ca5parAD"
@@ -0,0 +1,5 @@
internal = "Address Failing Unit Test for ``send_paid_media``"
[[pull_requests]]
uid = "4879"
author_uid = "Bibo-Joshi"
@@ -0,0 +1,6 @@
internal = "Improve Internal Logic for Network Retries"
[[pull_requests]]
uid = "4880"
author_uid = "Bibo-Joshi"
closes_threads = ["4871"]
@@ -0,0 +1,6 @@
features = "Add convenience properties for ``firstname``, ``lastname``, and ``username`` to ``SharedUser`` and ``ChatShared``"
internal = "Introduce utility module ``_utils.usernames`` refactoring convenience properties around Telegram Objects' ``firstname``, ``lastname``, and ``username``"
pull_requests = [
{ uid = "4881", author_uid = "aelkheir" },
{ uid = "4713", author_uid = "david-shiko" },
]
@@ -0,0 +1,10 @@
other = """
Set the default connection pool size for ``HTTPXRequest`` to 256 to allow more concurrent requests by default. Drop the ``httpx`` parameter ``max_keepalive_connections``. This way, the ``httpx`` default of 20 is used, leading to a smaller number of idle connections in large connection pools.
.. hint::
If you manually build the ``HTTPXRequest`` objects, please be aware that these changes also applies to you. Kindly double check your settings. To specify custom limits, you can set them via the parameter ``httpx_kwargs`` of ``HTTPXRequest``. See also `the httpx documentation <https://www.python-httpx.org/advanced/resource-limits/>`__ for more details on these settings."
"""
[[pull_requests]]
uid = "4882"
author_uid = "Poolitzer"
closes_threads = []
@@ -0,0 +1,5 @@
internal = "Add Copilot Instructions and Setup Steps"
[[pull_requests]]
uid = "4884"
author_uid = "harshil21"
closes_threads = []
@@ -0,0 +1,5 @@
internal = "Remove ``black``, ``isort``, ``flake8``, and ``pyupgrade`` in favor of ``ruff``"
[[pull_requests]]
uid = "4886"
author_uid = "harshil21"
closes_threads = []
@@ -0,0 +1,5 @@
internal = "Use Renovate to Keep Dependencies Up-To-Date"
[[pull_requests]]
uid = "4887"
author_uid = "renovate[bot]"
closes_threads = []
@@ -0,0 +1,5 @@
internal = "Add and use a ``uv.lock`` lockfile when setting up the development environment using ``uv``."
[[pull_requests]]
uid = "4890"
author_uid = "harshil21"
closes_threads = ["4796"]
@@ -0,0 +1,5 @@
internal = "Bump ``pytest`` from 8.4.0 to 8.4.1"
[[pull_requests]]
uid = "4892"
author_uid = "dependabot"
closes_threads = []
@@ -0,0 +1,5 @@
internal = "Bump ``pytest-xdist`` from 3.6.1 to 3.8.0"
[[pull_requests]]
uid = "4893"
author_uid = "dependabot"
closes_threads = []
@@ -0,0 +1,5 @@
documentation = "Bump ``furo`` from 2024.8.6 to 2025.7.19"
[[pull_requests]]
uid = "4894"
author_uid = "dependabot"
closes_threads = []
@@ -0,0 +1,5 @@
internal = "Bump ``astral-sh/setup-uv`` from 6.3.1 to 6.4.3"
[[pull_requests]]
uid = "4895"
author_uid = "dependabot"
closes_threads = []
@@ -0,0 +1,5 @@
internal = "Bump ``github/codeql-action`` from 3.29.2 to 3.29.5"
[[pull_requests]]
uid = "4896"
author_uid = "dependabot"
closes_threads = []
@@ -0,0 +1,5 @@
features = "Add ``filters.FORUM`` to filter messages from forum topic chats"
[[pull_requests]]
uid = "4906"
author_uid = "harshil21"
closes_threads = []
@@ -0,0 +1,5 @@
bugfixes = "Fix ``ResourceWarning`` when passing ``pathlib.Path`` objects to methods which accept file input"
[[pull_requests]]
uid = "4908"
author_uid = "harshil21"
closes_threads = ["4907"]
@@ -0,0 +1,14 @@
features = "Full Support for Bot API 9.2"
pull_requests = [
{ uid = "4911", author_uid = "aelkheir", closes_threads = ["4910"] },
{ uid = "4918", author_uid = "Poolitzer" },
{ uid = "4917", author_uid = "Poolitzer" },
{ uid = "4914", author_uid = "harshil21"},
{ uid = "4916", author_uid = "harshil21"},
{ uid = "4912", author_uid = "aelkheir" },
{ uid = "4921", author_uid = "aelkheir" },
{ uid = "4936", author_uid = "Bibo-Joshi" },
{ uid = "4935", author_uid = "Bibo-Joshi" },
{ uid = "4931", author_uid = "aelkheir" },
]
@@ -0,0 +1,5 @@
internal = "Don't update ``uv.lock`` in copilot runtime environment"
[[pull_requests]]
uid = "4915"
author_uid = "harshil21"
closes_threads = []
@@ -0,0 +1,5 @@
dependencies = "Update cachetools requirement from <6.2.0,>=5.3.3 to >=5.3.3,<6.3.0"
[[pull_requests]]
uid = "4923"
author_uid = "dependabot[bot]"
closes_threads = []
@@ -0,0 +1,5 @@
internal = "Bump actions/checkout from 4.2.2 to 5.0.0"
[[pull_requests]]
uid = "4925"
author_uid = "dependabot"
closes_threads = []
@@ -0,0 +1,5 @@
internal = "Bump codecov/codecov-action from 5.4.3 to 5.5.0"
[[pull_requests]]
uid = "4926"
author_uid = "dependabot"
closes_threads = []
@@ -0,0 +1,5 @@
internal = "Bump actions/download-artifact from 4.3.0 to 5.0.0"
[[pull_requests]]
uid = "4927"
author_uid = "dependabot"
closes_threads = []
@@ -0,0 +1,5 @@
internal = "Bump astral-sh/setup-uv from 6.4.3 to 6.6.1"
[[pull_requests]]
uid = "4928"
author_uid = "dependabot"
closes_threads = []
@@ -0,0 +1,5 @@
internal = "Bump github/codeql-action from 3.29.7 to 3.30.0"
[[pull_requests]]
uid = "4929"
author_uid = "dependabot"
closes_threads = []
@@ -0,0 +1,5 @@
internal = "Bump pytest from 8.4.1 to 8.4.2"
[[pull_requests]]
uid = "4933"
author_uid = "dependabot"
closes_threads = []
@@ -0,0 +1,5 @@
internal = "Use Tagged Release of `pydantic` in Development Dependencies"
[[pull_requests]]
uid = "4934"
author_uid = "harshil21"
closes_threads = ["4932"]
@@ -0,0 +1,5 @@
other = "Bump Version to v22.4"
[[pull_requests]]
uid = "4939"
author_uid = "Bibo-Joshi"
closes_threads = []
+1
View File
@@ -19,6 +19,7 @@
to link to the correct files & lines on github. Can be simplified once
https://github.com/sphinx-doc/sphinx/issues/1556 is closed
"""
import subprocess
from pathlib import Path
+4
View File
@@ -121,6 +121,10 @@
- Used for approving a chat join request
* - :meth:`~telegram.Bot.decline_chat_join_request`
- Used for declining a chat join request
* - :meth:`~telegram.Bot.approve_suggested_post`
- Used for approving a suggested post
* - :meth:`~telegram.Bot.decline_suggested_post`
- Used for declining a suggested post
* - :meth:`~telegram.Bot.ban_chat_member`
- Used for banning a member from the chat
* - :meth:`~telegram.Bot.unban_chat_member`
+9
View File
@@ -71,6 +71,7 @@ Available Types
telegram.contact
telegram.dice
telegram.directmessagepricechanged
telegram.directmessagestopic
telegram.document
telegram.externalreplyinfo
telegram.file
@@ -168,6 +169,14 @@ Available Types
telegram.storyareatypesuggestedreaction
telegram.storyareatypeuniquegift
telegram.storyareatypeweather
telegram.suggestedpostapprovalfailed
telegram.suggestedpostapproved
telegram.suggestedpostdeclined
telegram.suggestedpostinfo
telegram.suggestedpostpaid
telegram.suggestedpostparameters
telegram.suggestedpostprice
telegram.suggestedpostrefunded
telegram.switchinlinequerychosenchat
telegram.telegramobject
telegram.textquote
@@ -0,0 +1,6 @@
DirectMessagesTopic
===================
.. autoclass:: telegram.DirectMessagesTopic
:members:
:show-inheritance:
@@ -0,0 +1,6 @@
SuggestedPostApprovalFailed
===========================
.. autoclass:: telegram.SuggestedPostApprovalFailed
:members:
:show-inheritance:
@@ -0,0 +1,6 @@
SuggestedPostApproved
=====================
.. autoclass:: telegram.SuggestedPostApproved
:members:
:show-inheritance:
@@ -0,0 +1,6 @@
SuggestedPostDeclined
=====================
.. autoclass:: telegram.SuggestedPostDeclined
:members:
:show-inheritance:
@@ -0,0 +1,6 @@
SuggestedPostInfo
=================
.. autoclass:: telegram.SuggestedPostInfo
:members:
:show-inheritance:
@@ -0,0 +1,6 @@
SuggestedPostPaid
=================
.. autoclass:: telegram.SuggestedPostPaid
:members:
:show-inheritance:
@@ -0,0 +1,6 @@
SuggestedPostParameters
=======================
.. autoclass:: telegram.SuggestedPostParameters
:members:
:show-inheritance:
@@ -0,0 +1,6 @@
SuggestedPostPrice
==================
.. autoclass:: telegram.SuggestedPostPrice
:members:
:show-inheritance:
@@ -0,0 +1,6 @@
SuggestedPostRefunded
=====================
.. autoclass:: telegram.SuggestedPostRefunded
:members:
:show-inheritance:
+4
View File
@@ -96,6 +96,10 @@
.. |allow_paid_broadcast| replace:: Pass True to allow up to :tg-const:`telegram.constants.FloodLimit.PAID_MESSAGES_PER_SECOND` messages per second, ignoring `broadcasting limits <https://core.telegram.org/bots/faq#how-can-i-message-all-of-my-bot-39s-subscribers-at-once>`__ for a fee of 0.1 Telegram Stars per message. The relevant Stars will be withdrawn from the bot's balance.
.. |direct_messages_topic_id| replace:: Identifier of the direct messages topic to which the message will be sent; required if the message is sent to a direct messages chat.
.. |suggested_post_parameters| replace:: An object containing the parameters of the suggested post to send; for direct messages chats only. If the message is sent as a reply to another suggested post, then that suggested post is automatically declined.
.. |tz-naive-dtms| replace:: For timezone naive :obj:`datetime.datetime` objects, the default timezone of the bot will be used, which is UTC unless :attr:`telegram.ext.Defaults.tzinfo` is used.
.. |org-verify| replace:: `on behalf of the organization <https://telegram.org/verify#third-party-verification>`__
+1
View File
@@ -11,6 +11,7 @@ Note:
To use arbitrary callback data, you must install PTB via
`pip install "python-telegram-bot[callback-data]"`
"""
import logging
from typing import cast
+1
View File
@@ -13,6 +13,7 @@ Set bot Token, URL, admin CHAT_ID and PORT after the imports.
You may also need to change the `listen` value in the uvicorn configuration to match your setup.
Press Ctrl-C on the command line or send a signal to the process to stop the bot.
"""
import asyncio
import html
import json
+1
View File
@@ -13,6 +13,7 @@ Set bot Token, URL, admin CHAT_ID and PORT after the imports.
You may also need to change the `listen` value in the uvicorn configuration to match your setup.
Press Ctrl-C on the command line or send a signal to the process to stop the bot.
"""
import asyncio
import html
import logging
+1
View File
@@ -13,6 +13,7 @@ Set bot Token, URL, admin CHAT_ID and PORT after the imports.
You may also need to change the `listen` value in the uvicorn configuration to match your setup.
Press Ctrl-C on the command line or send a signal to the process to stop the bot.
"""
import asyncio
import html
import logging
@@ -13,6 +13,7 @@ Set bot Token, URL, admin CHAT_ID and PORT after the imports.
You may also need to change the `listen` value in the uvicorn configuration to match your setup.
Press Ctrl-C on the command line or send a signal to the process to stop the bot.
"""
import asyncio
import html
import logging
+1
View File
@@ -3,6 +3,7 @@
# This program is dedicated to the public domain under the CC0 license.
"""This is a very simple example on how one could implement a custom error handler."""
import html
import json
import logging
+1
View File
@@ -14,6 +14,7 @@ Basic inline bot example. Applies different text transformations.
Press Ctrl-C on the command line or send a signal to the process to stop the
bot.
"""
import logging
from html import escape
from uuid import uuid4
+1
View File
@@ -6,6 +6,7 @@
Basic example for a bot that uses inline keyboards. For an in-depth explanation, check out
https://github.com/python-telegram-bot/python-telegram-bot/wiki/InlineKeyboard-Example.
"""
import logging
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
+1
View File
@@ -14,6 +14,7 @@ ConversationHandler.
Send /start to initiate the conversation.
Press Ctrl-C on the command line to stop the bot.
"""
import logging
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
+1
View File
@@ -14,6 +14,7 @@ Note:
To use Telegram Passport, you must install PTB via
`pip install "python-telegram-bot[passport]"`
"""
import logging
from pathlib import Path
+1
View File
@@ -7,6 +7,7 @@ Basic example for a bot that works with polls. Only 3 people are allowed to inte
poll/quiz the bot generates. The preview command generates a closed poll/quiz, exactly like the
one the user sends the bot
"""
import logging
from telegram import (
+1
View File
@@ -5,6 +5,7 @@ This is built on the API wrapper, see echobot.py to see the same example built
on the telegram.ext bot framework.
This program is dedicated to the public domain under the CC0 license.
"""
import asyncio
import contextlib
import datetime as dtm
+1
View File
@@ -8,6 +8,7 @@ The static website for this website is hosted by the PTB team for your convenien
Currently only showcases starting the WebApp via a KeyboardButton, as all other methods would
require a bot token.
"""
import json
import logging
+18 -25
View File
@@ -52,14 +52,12 @@ dependencies = [
"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
# Make sure to install those as additional_dependencies in the pre-commit hooks
#
# 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
# When adding new extras, make sure to update `ext` and `all` accordingly
# Optional dependencies for production
all = [
@@ -67,7 +65,7 @@ all = [
]
callback-data = [
# Cachetools doesn't have a strict stability policy. Let's be cautious for now.
"cachetools>=5.3.3,<6.2.0",
"cachetools>=5.3.3,<6.3.0",
]
ext = [
"python-telegram-bot[callback-data,job-queue,rate-limiter,webhooks]",
@@ -100,11 +98,11 @@ tests = [
# required for building the wheels for releases
"build",
# For the test suite
"pytest==8.4.0",
"pytest==8.4.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",
"pytest-xdist==3.8.0",
# Used for flaky tests (flaky decorator)
"flaky>=3.8.1",
# used in test_official for parsing tg docs
@@ -120,7 +118,7 @@ tests = [
docs = [
"chango~=0.4.0; python_version >= '3.12'",
"sphinx==8.2.3; python_version >= '3.11'",
"furo==2024.8.6",
"furo==2025.7.19",
"sphinx-paramlinks==0.6.0",
"sphinxcontrib-mermaid==1.0.0",
"sphinx-copybutton==0.5.2",
@@ -128,14 +126,18 @@ docs = [
# Temporary. See #4387
"sphinx-build-compatibility @ git+https://github.com/readthedocs/sphinx-build-compatibility.git@58aabc5f207c6c2421f23d3578adc0b14af57047",
# For python 3.14 support, we need a version of pydantic-core >= 2.35.0, since it upgrades the
# rust toolchain, required for building the project. But there isn't a version of pydantic
# which allows that pydantic-core version yet, so we use the latest commit on the
# pydantic repository, which has the required version of pydantic-core.
# This should ideally be done in `chango`'s dependencies. We can remove this once a new pydantic
# version is released.
"pydantic @ git+https://github.com/pydantic/pydantic ; python_version >= '3.14'"
# rust toolchain, required for building the project.
# This should ideally be done in `chango`'s dependencies. We can remove this once a new
# stable pydantic version is released.
"pydantic >= 2.12.0a1 ; python_version >= '3.14'"
]
all = ["pre-commit", { include-group = "tests" }, { include-group = "docs" }]
linting = [
"pre-commit",
"ruff==0.12.7",
"mypy==1.16.1",
"pylint==3.3.7"
]
all = [{ include-group = "tests" }, { include-group = "docs" }, { include-group = "linting"}]
# HATCH
[tool.hatch.version]
@@ -146,7 +148,7 @@ path = "src/telegram/_version.py"
# See also https://github.com/pypa/hatch/issues/1230 for discussion
# the source distribution will include most of the files in the root directory
[tool.hatch.build.targets.sdist]
exclude = [".venv*", "venv*", ".github"]
exclude = [".venv*", "venv*", ".github", "uv.lock"]
# the wheel will only include the src/telegram package
[tool.hatch.build.targets.wheel]
packages = ["src/telegram"]
@@ -156,15 +158,6 @@ packages = ["src/telegram"]
sys_path = "changes"
chango_instance = { name= "chango_instance", module = "config" }
# BLACK:
[tool.black]
line-length = 99
# ISORT:
[tool.isort] # black config
profile = "black"
line_length = 99
# RUFF:
[tool.ruff]
line-length = 99
-5
View File
@@ -1,5 +0,0 @@
[flake8]
max-line-length = 99
ignore = W503, W605
extend-ignore = E203, E704
exclude = docs/source/conf.py
+20
View File
@@ -93,6 +93,7 @@ __all__ = (
"DataCredentials",
"Dice",
"DirectMessagePriceChanged",
"DirectMessagesTopic",
"Document",
"EncryptedCredentials",
"EncryptedPassportElement",
@@ -264,6 +265,14 @@ __all__ = (
"StoryAreaTypeUniqueGift",
"StoryAreaTypeWeather",
"SuccessfulPayment",
"SuggestedPostApprovalFailed",
"SuggestedPostApproved",
"SuggestedPostDeclined",
"SuggestedPostInfo",
"SuggestedPostPaid",
"SuggestedPostParameters",
"SuggestedPostPrice",
"SuggestedPostRefunded",
"SwitchInlineQueryChosenChat",
"TelegramObject",
"TextQuote",
@@ -394,6 +403,7 @@ from ._choseninlineresult import ChosenInlineResult
from ._copytextbutton import CopyTextButton
from ._dice import Dice
from ._directmessagepricechanged import DirectMessagePriceChanged
from ._directmessagestopic import DirectMessagesTopic
from ._files._inputstorycontent import (
InputStoryContent,
InputStoryContentPhoto,
@@ -571,6 +581,16 @@ from ._storyarea import (
StoryAreaTypeUniqueGift,
StoryAreaTypeWeather,
)
from ._suggestedpost import (
SuggestedPostApprovalFailed,
SuggestedPostApproved,
SuggestedPostDeclined,
SuggestedPostInfo,
SuggestedPostPaid,
SuggestedPostParameters,
SuggestedPostPrice,
SuggestedPostRefunded,
)
from ._switchinlinequerychosenchat import SwitchInlineQueryChosenChat
from ._telegramobject import TelegramObject
from ._uniquegift import (
+1
View File
@@ -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 Birthday."""
import datetime as dtm
from typing import Optional
+339 -7
View File
@@ -136,6 +136,7 @@ if TYPE_CHECKING:
PassportElementError,
ShippingOption,
StoryArea,
SuggestedPostParameters,
)
BT = TypeVar("BT", bound="Bot")
@@ -339,7 +340,11 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
self._initialized: bool = False
self._request: tuple[BaseRequest, BaseRequest] = (
HTTPXRequest() if get_updates_request is None else get_updates_request,
(
HTTPXRequest(connection_pool_size=1)
if get_updates_request is None
else get_updates_request
),
HTTPXRequest() if request is None else request,
)
@@ -754,6 +759,8 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
business_connection_id: Optional[str] = None,
message_effect_id: Optional[str] = None,
allow_paid_broadcast: Optional[bool] = None,
direct_messages_topic_id: Optional[int] = None,
suggested_post_parameters: Optional["SuggestedPostParameters"] = None,
*,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
reply_to_message_id: Optional[int] = None,
@@ -796,6 +803,7 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
"business_connection_id": business_connection_id,
"caption": caption,
"caption_entities": caption_entities,
"direct_messages_topic_id": direct_messages_topic_id,
"disable_notification": disable_notification,
"link_preview_options": link_preview_options,
"message_thread_id": message_thread_id,
@@ -804,6 +812,7 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
"protect_content": protect_content,
"reply_markup": reply_markup,
"reply_parameters": reply_parameters,
"suggested_post_parameters": suggested_post_parameters,
}
)
@@ -999,6 +1008,8 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
business_connection_id: Optional[str] = None,
message_effect_id: Optional[str] = None,
allow_paid_broadcast: Optional[bool] = None,
direct_messages_topic_id: Optional[int] = None,
suggested_post_parameters: Optional["SuggestedPostParameters"] = None,
*,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
reply_to_message_id: Optional[int] = None,
@@ -1053,6 +1064,13 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
allow_paid_broadcast (:obj:`bool`, optional): |allow_paid_broadcast|
.. versionadded:: 21.7
suggested_post_parameters (:class:`telegram.SuggestedPostParameters`, optional):
|suggested_post_parameters|
.. versionadded:: 22.4
direct_messages_topic_id (:obj:`int`, optional): |direct_messages_topic_id|
.. versionadded:: 22.4
Keyword Args:
allow_sending_without_reply (:obj:`bool`, optional): |allow_sending_without_reply|
@@ -1112,6 +1130,8 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
reply_parameters=reply_parameters,
message_effect_id=message_effect_id,
allow_paid_broadcast=allow_paid_broadcast,
direct_messages_topic_id=direct_messages_topic_id,
suggested_post_parameters=suggested_post_parameters,
read_timeout=read_timeout,
write_timeout=write_timeout,
connect_timeout=connect_timeout,
@@ -1228,6 +1248,8 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
protect_content: ODVInput[bool] = DEFAULT_NONE,
message_thread_id: Optional[int] = None,
video_start_timestamp: Optional[int] = None,
direct_messages_topic_id: Optional[int] = None,
suggested_post_parameters: Optional["SuggestedPostParameters"] = None,
*,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
@@ -1263,6 +1285,16 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
message_thread_id (:obj:`int`, optional): |message_thread_id_arg|
.. versionadded:: 20.0
suggested_post_parameters (:class:`telegram.SuggestedPostParameters`, optional): An
object containing the parameters of the suggested post to send; for direct messages
chats only.
.. versionadded:: 22.4
direct_messages_topic_id (:obj:`int`, optional): Identifier of the direct messages
topic to which the message will be forwarded; required if the message is
forwarded to a direct messages chat.
.. versionadded:: 22.4
Returns:
:class:`telegram.Message`: On success, the sent Message is returned.
@@ -1283,11 +1315,13 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
disable_notification=disable_notification,
protect_content=protect_content,
message_thread_id=message_thread_id,
suggested_post_parameters=suggested_post_parameters,
read_timeout=read_timeout,
write_timeout=write_timeout,
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
api_kwargs=api_kwargs,
direct_messages_topic_id=direct_messages_topic_id,
)
async def forward_messages(
@@ -1298,6 +1332,7 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
disable_notification: ODVInput[bool] = DEFAULT_NONE,
protect_content: ODVInput[bool] = DEFAULT_NONE,
message_thread_id: Optional[int] = None,
direct_messages_topic_id: Optional[int] = None,
*,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
@@ -1324,6 +1359,11 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
disable_notification (:obj:`bool`, optional): |disable_notification|
protect_content (:obj:`bool`, optional): |protect_content|
message_thread_id (:obj:`int`, optional): |message_thread_id_arg|
direct_messages_topic_id (:obj:`int`, optional): Identifier of the direct messages
topic to which the messages will be forwarded; required if the messages are
forwarded to a direct messages chat.
.. versionadded:: 22.4
Returns:
tuple[:class:`telegram.Message`]: On success, a tuple of ``MessageId`` of sent messages
@@ -1339,6 +1379,7 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
"disable_notification": disable_notification,
"protect_content": protect_content,
"message_thread_id": message_thread_id,
"direct_messages_topic_id": direct_messages_topic_id,
}
result = await self._post(
@@ -1369,6 +1410,8 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
message_effect_id: Optional[str] = None,
allow_paid_broadcast: Optional[bool] = None,
show_caption_above_media: Optional[bool] = None,
direct_messages_topic_id: Optional[int] = None,
suggested_post_parameters: Optional["SuggestedPostParameters"] = None,
*,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
reply_to_message_id: Optional[int] = None,
@@ -1441,6 +1484,13 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
show_caption_above_media (:obj:`bool`, optional): Pass |show_cap_above_med|
.. versionadded:: 21.3
suggested_post_parameters (:class:`telegram.SuggestedPostParameters`, optional):
|suggested_post_parameters|
.. versionadded:: 22.4
direct_messages_topic_id (:obj:`int`, optional): |direct_messages_topic_id|
.. versionadded:: 22.4
Keyword Args:
allow_sending_without_reply (:obj:`bool`, optional): |allow_sending_without_reply|
@@ -1502,6 +1552,8 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
business_connection_id=business_connection_id,
message_effect_id=message_effect_id,
allow_paid_broadcast=allow_paid_broadcast,
direct_messages_topic_id=direct_messages_topic_id,
suggested_post_parameters=suggested_post_parameters,
)
async def send_audio(
@@ -1523,6 +1575,8 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
business_connection_id: Optional[str] = None,
message_effect_id: Optional[str] = None,
allow_paid_broadcast: Optional[bool] = None,
direct_messages_topic_id: Optional[int] = None,
suggested_post_parameters: Optional["SuggestedPostParameters"] = None,
*,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
reply_to_message_id: Optional[int] = None,
@@ -1605,6 +1659,13 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
allow_paid_broadcast (:obj:`bool`, optional): |allow_paid_broadcast|
.. versionadded:: 21.7
suggested_post_parameters (:class:`telegram.SuggestedPostParameters`, optional):
|suggested_post_parameters|
.. versionadded:: 22.4
direct_messages_topic_id (:obj:`int`, optional): |direct_messages_topic_id|
.. versionadded:: 22.4
Keyword Args:
allow_sending_without_reply (:obj:`bool`, optional): |allow_sending_without_reply|
@@ -1668,6 +1729,8 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
business_connection_id=business_connection_id,
message_effect_id=message_effect_id,
allow_paid_broadcast=allow_paid_broadcast,
direct_messages_topic_id=direct_messages_topic_id,
suggested_post_parameters=suggested_post_parameters,
)
async def send_document(
@@ -1687,6 +1750,8 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
business_connection_id: Optional[str] = None,
message_effect_id: Optional[str] = None,
allow_paid_broadcast: Optional[bool] = None,
direct_messages_topic_id: Optional[int] = None,
suggested_post_parameters: Optional["SuggestedPostParameters"] = None,
*,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
reply_to_message_id: Optional[int] = None,
@@ -1764,6 +1829,13 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
allow_paid_broadcast (:obj:`bool`, optional): |allow_paid_broadcast|
.. versionadded:: 21.7
suggested_post_parameters (:class:`telegram.SuggestedPostParameters`, optional):
|suggested_post_parameters|
.. versionadded:: 22.4
direct_messages_topic_id (:obj:`int`, optional): |direct_messages_topic_id|
.. versionadded:: 22.4
Keyword Args:
allow_sending_without_reply (:obj:`bool`, optional): |allow_sending_without_reply|
@@ -1823,6 +1895,8 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
business_connection_id=business_connection_id,
message_effect_id=message_effect_id,
allow_paid_broadcast=allow_paid_broadcast,
direct_messages_topic_id=direct_messages_topic_id,
suggested_post_parameters=suggested_post_parameters,
)
async def send_sticker(
@@ -1838,6 +1912,8 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
business_connection_id: Optional[str] = None,
message_effect_id: Optional[str] = None,
allow_paid_broadcast: Optional[bool] = None,
direct_messages_topic_id: Optional[int] = None,
suggested_post_parameters: Optional["SuggestedPostParameters"] = None,
*,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
reply_to_message_id: Optional[int] = None,
@@ -1895,6 +1971,13 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
allow_paid_broadcast (:obj:`bool`, optional): |allow_paid_broadcast|
.. versionadded:: 21.7
suggested_post_parameters (:class:`telegram.SuggestedPostParameters`, optional):
|suggested_post_parameters|
.. versionadded:: 22.4
direct_messages_topic_id (:obj:`int`, optional): |direct_messages_topic_id|
.. versionadded:: 22.4
Keyword Args:
allow_sending_without_reply (:obj:`bool`, optional): |allow_sending_without_reply|
@@ -1946,6 +2029,8 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
business_connection_id=business_connection_id,
message_effect_id=message_effect_id,
allow_paid_broadcast=allow_paid_broadcast,
direct_messages_topic_id=direct_messages_topic_id,
suggested_post_parameters=suggested_post_parameters,
)
async def send_video(
@@ -1972,6 +2057,8 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
show_caption_above_media: Optional[bool] = None,
cover: Optional[FileInput] = None,
start_timestamp: Optional[int] = None,
direct_messages_topic_id: Optional[int] = None,
suggested_post_parameters: Optional["SuggestedPostParameters"] = None,
*,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
reply_to_message_id: Optional[int] = None,
@@ -2072,6 +2159,13 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
show_caption_above_media (:obj:`bool`, optional): Pass |show_cap_above_med|
.. versionadded:: 21.3
suggested_post_parameters (:class:`telegram.SuggestedPostParameters`, optional):
|suggested_post_parameters|
.. versionadded:: 22.4
direct_messages_topic_id (:obj:`int`, optional): |direct_messages_topic_id|
.. versionadded:: 22.4
Keyword Args:
allow_sending_without_reply (:obj:`bool`, optional): |allow_sending_without_reply|
@@ -2140,6 +2234,8 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
business_connection_id=business_connection_id,
message_effect_id=message_effect_id,
allow_paid_broadcast=allow_paid_broadcast,
direct_messages_topic_id=direct_messages_topic_id,
suggested_post_parameters=suggested_post_parameters,
)
async def send_video_note(
@@ -2157,6 +2253,8 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
business_connection_id: Optional[str] = None,
message_effect_id: Optional[str] = None,
allow_paid_broadcast: Optional[bool] = None,
direct_messages_topic_id: Optional[int] = None,
suggested_post_parameters: Optional["SuggestedPostParameters"] = None,
*,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
reply_to_message_id: Optional[int] = None,
@@ -2233,6 +2331,13 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
allow_paid_broadcast (:obj:`bool`, optional): |allow_paid_broadcast|
.. versionadded:: 21.7
suggested_post_parameters (:class:`telegram.SuggestedPostParameters`, optional):
|suggested_post_parameters|
.. versionadded:: 22.4
direct_messages_topic_id (:obj:`int`, optional): |direct_messages_topic_id|
.. versionadded:: 22.4
Keyword Args:
allow_sending_without_reply (:obj:`bool`, optional): |allow_sending_without_reply|
@@ -2292,6 +2397,8 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
business_connection_id=business_connection_id,
message_effect_id=message_effect_id,
allow_paid_broadcast=allow_paid_broadcast,
direct_messages_topic_id=direct_messages_topic_id,
suggested_post_parameters=suggested_post_parameters,
)
async def send_animation(
@@ -2315,6 +2422,8 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
message_effect_id: Optional[str] = None,
allow_paid_broadcast: Optional[bool] = None,
show_caption_above_media: Optional[bool] = None,
direct_messages_topic_id: Optional[int] = None,
suggested_post_parameters: Optional["SuggestedPostParameters"] = None,
*,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
reply_to_message_id: Optional[int] = None,
@@ -2402,6 +2511,13 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
show_caption_above_media (:obj:`bool`, optional): Pass |show_cap_above_med|
.. versionadded:: 21.3
suggested_post_parameters (:class:`telegram.SuggestedPostParameters`, optional):
|suggested_post_parameters|
.. versionadded:: 22.4
direct_messages_topic_id (:obj:`int`, optional): |direct_messages_topic_id|
.. versionadded:: 22.4
Keyword Args:
allow_sending_without_reply (:obj:`bool`, optional): |allow_sending_without_reply|
@@ -2467,6 +2583,8 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
business_connection_id=business_connection_id,
message_effect_id=message_effect_id,
allow_paid_broadcast=allow_paid_broadcast,
direct_messages_topic_id=direct_messages_topic_id,
suggested_post_parameters=suggested_post_parameters,
)
async def send_voice(
@@ -2485,6 +2603,8 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
business_connection_id: Optional[str] = None,
message_effect_id: Optional[str] = None,
allow_paid_broadcast: Optional[bool] = None,
direct_messages_topic_id: Optional[int] = None,
suggested_post_parameters: Optional["SuggestedPostParameters"] = None,
*,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
reply_to_message_id: Optional[int] = None,
@@ -2563,6 +2683,13 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
allow_paid_broadcast (:obj:`bool`, optional): |allow_paid_broadcast|
.. versionadded:: 21.7
suggested_post_parameters (:class:`telegram.SuggestedPostParameters`, optional):
|suggested_post_parameters|
.. versionadded:: 22.4
direct_messages_topic_id (:obj:`int`, optional): |direct_messages_topic_id|
.. versionadded:: 22.4
Keyword Args:
allow_sending_without_reply (:obj:`bool`, optional): |allow_sending_without_reply|
@@ -2623,6 +2750,8 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
business_connection_id=business_connection_id,
message_effect_id=message_effect_id,
allow_paid_broadcast=allow_paid_broadcast,
direct_messages_topic_id=direct_messages_topic_id,
suggested_post_parameters=suggested_post_parameters,
)
async def send_media_group(
@@ -2638,6 +2767,7 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
business_connection_id: Optional[str] = None,
message_effect_id: Optional[str] = None,
allow_paid_broadcast: Optional[bool] = None,
direct_messages_topic_id: Optional[int] = None,
*,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
reply_to_message_id: Optional[int] = None,
@@ -2694,6 +2824,12 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
allow_paid_broadcast (:obj:`bool`, optional): |allow_paid_broadcast|
.. versionadded:: 21.7
direct_messages_topic_id (:obj:`int`, optional): Identifier of the direct messages
topic to which the messages will be sent; required if the messages are sent to a
direct messages chat.
.. versionadded:: 22.4
Keyword Args:
allow_sending_without_reply (:obj:`bool`, optional): |allow_sending_without_reply|
@@ -2789,6 +2925,7 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
"business_connection_id": business_connection_id,
"message_effect_id": message_effect_id,
"allow_paid_broadcast": allow_paid_broadcast,
"direct_messages_topic_id": direct_messages_topic_id,
}
result = await self._post(
@@ -2820,6 +2957,8 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
business_connection_id: Optional[str] = None,
message_effect_id: Optional[str] = None,
allow_paid_broadcast: Optional[bool] = None,
direct_messages_topic_id: Optional[int] = None,
suggested_post_parameters: Optional["SuggestedPostParameters"] = None,
*,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
reply_to_message_id: Optional[int] = None,
@@ -2886,6 +3025,13 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
allow_paid_broadcast (:obj:`bool`, optional): |allow_paid_broadcast|
.. versionadded:: 21.7
suggested_post_parameters (:class:`telegram.SuggestedPostParameters`, optional):
|suggested_post_parameters|
.. versionadded:: 22.4
direct_messages_topic_id (:obj:`int`, optional): |direct_messages_topic_id|
.. versionadded:: 22.4
Keyword Args:
allow_sending_without_reply (:obj:`bool`, optional): |allow_sending_without_reply|
@@ -2957,6 +3103,8 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
business_connection_id=business_connection_id,
message_effect_id=message_effect_id,
allow_paid_broadcast=allow_paid_broadcast,
direct_messages_topic_id=direct_messages_topic_id,
suggested_post_parameters=suggested_post_parameters,
)
async def edit_message_live_location(
@@ -3144,6 +3292,8 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
business_connection_id: Optional[str] = None,
message_effect_id: Optional[str] = None,
allow_paid_broadcast: Optional[bool] = None,
direct_messages_topic_id: Optional[int] = None,
suggested_post_parameters: Optional["SuggestedPostParameters"] = None,
*,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
reply_to_message_id: Optional[int] = None,
@@ -3202,6 +3352,13 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
allow_paid_broadcast (:obj:`bool`, optional): |allow_paid_broadcast|
.. versionadded:: 21.7
suggested_post_parameters (:class:`telegram.SuggestedPostParameters`, optional):
|suggested_post_parameters|
.. versionadded:: 22.4
direct_messages_topic_id (:obj:`int`, optional): |direct_messages_topic_id|
.. versionadded:: 22.4
Keyword Args:
allow_sending_without_reply (:obj:`bool`, optional): |allow_sending_without_reply|
@@ -3284,6 +3441,8 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
business_connection_id=business_connection_id,
message_effect_id=message_effect_id,
allow_paid_broadcast=allow_paid_broadcast,
direct_messages_topic_id=direct_messages_topic_id,
suggested_post_parameters=suggested_post_parameters,
)
async def send_contact(
@@ -3301,6 +3460,8 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
business_connection_id: Optional[str] = None,
message_effect_id: Optional[str] = None,
allow_paid_broadcast: Optional[bool] = None,
direct_messages_topic_id: Optional[int] = None,
suggested_post_parameters: Optional["SuggestedPostParameters"] = None,
*,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
reply_to_message_id: Optional[int] = None,
@@ -3349,6 +3510,13 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
allow_paid_broadcast (:obj:`bool`, optional): |allow_paid_broadcast|
.. versionadded:: 21.7
suggested_post_parameters (:class:`telegram.SuggestedPostParameters`, optional):
|suggested_post_parameters|
.. versionadded:: 22.4
direct_messages_topic_id (:obj:`int`, optional): |direct_messages_topic_id|
.. versionadded:: 22.4
Keyword Args:
allow_sending_without_reply (:obj:`bool`, optional): |allow_sending_without_reply|
@@ -3422,6 +3590,8 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
business_connection_id=business_connection_id,
message_effect_id=message_effect_id,
allow_paid_broadcast=allow_paid_broadcast,
direct_messages_topic_id=direct_messages_topic_id,
suggested_post_parameters=suggested_post_parameters,
)
async def send_game(
@@ -3620,8 +3790,7 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
next_offset_int = current_offset_int + 1
next_offset = str(next_offset_int)
effective_results = results[
current_offset_int
* InlineQueryLimit.RESULTS : next_offset_int
current_offset_int * InlineQueryLimit.RESULTS : next_offset_int
* InlineQueryLimit.RESULTS
]
else:
@@ -5228,6 +5397,8 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
reply_parameters: Optional["ReplyParameters"] = None,
message_effect_id: Optional[str] = None,
allow_paid_broadcast: Optional[bool] = None,
direct_messages_topic_id: Optional[int] = None,
suggested_post_parameters: Optional["SuggestedPostParameters"] = None,
*,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
reply_to_message_id: Optional[int] = None,
@@ -5348,6 +5519,13 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
allow_paid_broadcast (:obj:`bool`, optional): |allow_paid_broadcast|
.. versionadded:: 21.7
suggested_post_parameters (:class:`telegram.SuggestedPostParameters`, optional):
|suggested_post_parameters|
.. versionadded:: 22.4
direct_messages_topic_id (:obj:`int`, optional): |direct_messages_topic_id|
.. versionadded:: 22.4
Keyword Args:
allow_sending_without_reply (:obj:`bool`, optional): |allow_sending_without_reply|
@@ -5418,6 +5596,8 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
api_kwargs=api_kwargs,
message_effect_id=message_effect_id,
allow_paid_broadcast=allow_paid_broadcast,
direct_messages_topic_id=direct_messages_topic_id,
suggested_post_parameters=suggested_post_parameters,
)
async def answer_shipping_query(
@@ -5670,6 +5850,7 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
can_post_stories: Optional[bool] = None,
can_edit_stories: Optional[bool] = None,
can_delete_stories: Optional[bool] = None,
can_manage_direct_messages: Optional[bool] = None,
*,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
@@ -5738,6 +5919,11 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
delete stories posted by other users.
.. versionadded:: 20.6
can_manage_direct_messages (:obj:`bool`, optional): Pass :obj:`True`, if the
administrator can manage direct messages within the channel and decline suggested
posts; for channels only
.. versionadded:: 22.4
Returns:
:obj:`bool`: On success, :obj:`True` is returned.
@@ -5764,6 +5950,7 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
"can_post_stories": can_post_stories,
"can_edit_stories": can_edit_stories,
"can_delete_stories": can_delete_stories,
"can_manage_direct_messages": can_manage_direct_messages,
}
return await self._post(
@@ -7704,6 +7891,8 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
business_connection_id: Optional[str] = None,
message_effect_id: Optional[str] = None,
allow_paid_broadcast: Optional[bool] = None,
direct_messages_topic_id: Optional[int] = None,
suggested_post_parameters: Optional["SuggestedPostParameters"] = None,
*,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
reply_to_message_id: Optional[int] = None,
@@ -7756,6 +7945,13 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
allow_paid_broadcast (:obj:`bool`, optional): |allow_paid_broadcast|
.. versionadded:: 21.7
suggested_post_parameters (:class:`telegram.SuggestedPostParameters`, optional):
|suggested_post_parameters|
.. versionadded:: 22.4
direct_messages_topic_id (:obj:`int`, optional): |direct_messages_topic_id|
.. versionadded:: 22.4
Keyword Args:
allow_sending_without_reply (:obj:`bool`, optional): |allow_sending_without_reply|
@@ -7805,6 +8001,8 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
business_connection_id=business_connection_id,
message_effect_id=message_effect_id,
allow_paid_broadcast=allow_paid_broadcast,
direct_messages_topic_id=direct_messages_topic_id,
suggested_post_parameters=suggested_post_parameters,
)
async def get_my_default_administrator_rights(
@@ -8137,6 +8335,8 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
show_caption_above_media: Optional[bool] = None,
allow_paid_broadcast: Optional[bool] = None,
video_start_timestamp: Optional[int] = None,
direct_messages_topic_id: Optional[int] = None,
suggested_post_parameters: Optional["SuggestedPostParameters"] = None,
*,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
reply_to_message_id: Optional[int] = None,
@@ -8191,6 +8391,13 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
allow_paid_broadcast (:obj:`bool`, optional): |allow_paid_broadcast|
.. versionadded:: 21.7
suggested_post_parameters (:class:`telegram.SuggestedPostParameters`, optional):
|suggested_post_parameters|
.. versionadded:: 22.4
direct_messages_topic_id (:obj:`int`, optional): |direct_messages_topic_id|
.. versionadded:: 22.4
Keyword Args:
allow_sending_without_reply (:obj:`bool`, optional): |allow_sending_without_reply|
@@ -8250,7 +8457,9 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
"reply_parameters": reply_parameters,
"show_caption_above_media": show_caption_above_media,
"allow_paid_broadcast": allow_paid_broadcast,
"direct_messages_topic_id": direct_messages_topic_id,
"video_start_timestamp": video_start_timestamp,
"suggested_post_parameters": suggested_post_parameters,
}
result = await self._post(
@@ -8273,6 +8482,7 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
protect_content: ODVInput[bool] = DEFAULT_NONE,
message_thread_id: Optional[int] = None,
remove_caption: Optional[bool] = None,
direct_messages_topic_id: Optional[int] = None,
*,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
@@ -8305,6 +8515,12 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
message_thread_id (:obj:`int`, optional): |message_thread_id_arg|
remove_caption (:obj:`bool`, optional): Pass :obj:`True` to copy the messages without
their captions.
direct_messages_topic_id (:obj:`int`, optional): Identifier of the direct messages
topic to which the message will be sent; required if the message is sent to a
direct messages chat.
.. versionadded:: 22.4
Returns:
tuple[:class:`telegram.MessageId`]: On success, a tuple of :class:`~telegram.MessageId`
@@ -8322,6 +8538,7 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
"protect_content": protect_content,
"message_thread_id": message_thread_id,
"remove_caption": remove_caption,
"direct_messages_topic_id": direct_messages_topic_id,
}
result = await self._post(
@@ -10726,6 +10943,9 @@ CHAT_ACTIVITY_TIMEOUT` seconds.
business_connection_id: Optional[str] = None,
payload: Optional[str] = None,
allow_paid_broadcast: Optional[bool] = None,
direct_messages_topic_id: Optional[int] = None,
suggested_post_parameters: Optional["SuggestedPostParameters"] = None,
message_thread_id: Optional[int] = None,
*,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
reply_to_message_id: Optional[int] = None,
@@ -10772,6 +10992,16 @@ CHAT_ACTIVITY_TIMEOUT` seconds.
allow_paid_broadcast (:obj:`bool`, optional): |allow_paid_broadcast|
.. versionadded:: 21.7
suggested_post_parameters (:class:`telegram.SuggestedPostParameters`, optional):
|suggested_post_parameters|
.. versionadded:: 22.4
direct_messages_topic_id (:obj:`int`, optional): |direct_messages_topic_id|
.. versionadded:: 22.4
message_thread_id (:obj:`int`, optional): |message_thread_id_arg|
.. versionadded:: 22.4
Keyword Args:
allow_sending_without_reply (:obj:`bool`, optional): |allow_sending_without_reply|
@@ -10816,6 +11046,9 @@ CHAT_ACTIVITY_TIMEOUT` seconds.
api_kwargs=api_kwargs,
business_connection_id=business_connection_id,
allow_paid_broadcast=allow_paid_broadcast,
direct_messages_topic_id=direct_messages_topic_id,
suggested_post_parameters=suggested_post_parameters,
message_thread_id=message_thread_id,
)
async def create_chat_subscription_invite_link(
@@ -11144,8 +11377,6 @@ CHAT_ACTIVITY_TIMEOUT` seconds.
"""Removes verification from a chat that is currently verified |org-verify|
represented by the bot.
.. versionadded:: 21.10
Args:
@@ -11183,8 +11414,6 @@ CHAT_ACTIVITY_TIMEOUT` seconds.
"""Removes verification from a user who is currently verified |org-verify|
represented by the bot.
.. versionadded:: 21.10
Args:
@@ -11239,6 +11468,105 @@ CHAT_ACTIVITY_TIMEOUT` seconds.
)
)
async def approve_suggested_post(
self,
chat_id: int,
message_id: int,
send_date: Optional[Union[int, dtm.datetime]] = 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,
) -> bool:
"""
Use this method to approve a suggested post in a direct messages chat.
The bot must have the :attr:`~telegram.ChatMemberAdministrator.can_post_messages`
administrator right in the corresponding channel chat.
.. versionadded:: 22.4
Args:
chat_id (:obj:`int`): Unique identifier of the target direct messages chat.
message_id (:obj:`int`): Identifier of a suggested post message to approve.
send_date (:obj:`int` | :obj:`datetime.datetime`, optional): Date when the post is
expected to be published; omit if the date has already been specified when the
suggested post was created. If specified, then the date must be not more than
:tg-const:`telegram.constants.SuggestedPost.MAX_SEND_DATE` seconds (30 days)
in the future.
|tz-naive-dtms|
Returns:
:obj:`bool`: On success, :obj:`True` is returned.
Raises:
:class:`telegram.error.TelegramError`
"""
data: JSONDict = {
"chat_id": chat_id,
"message_id": message_id,
"send_date": send_date,
}
return await self._post(
"approveSuggestedPost",
data,
read_timeout=read_timeout,
write_timeout=write_timeout,
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
api_kwargs=api_kwargs,
)
async def decline_suggested_post(
self,
chat_id: int,
message_id: int,
comment: 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,
) -> bool:
"""
Use this method to decline a suggested post in a direct messages chat.
The bot must have the :attr:`~telegram.ChatMemberAdministrator.can_manage_direct_messages`
administrator right in the corresponding channel chat.
.. versionadded:: 22.4
Args:
chat_id (:obj:`int`): Unique identifier of the target direct messages chat.
message_id (:obj:`int`): Identifier of a suggested post message to decline.
comment (:obj:`str`, optional): Comment for the creator of the suggested post.
0-:tg-const:`telegram.constants.SuggestedPost.MAX_COMMENT_LENGTH` characters.
Returns:
:obj:`bool`: On success, :obj:`True` is returned.
Raises:
:class:`telegram.error.TelegramError`
"""
data: JSONDict = {
"chat_id": chat_id,
"message_id": message_id,
"comment": comment,
}
return await self._post(
"declineSuggestedPost",
data,
read_timeout=read_timeout,
write_timeout=write_timeout,
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
api_kwargs=api_kwargs,
)
def to_dict(self, recursive: bool = True) -> JSONDict: # noqa: ARG002
"""See :meth:`telegram.TelegramObject.to_dict`."""
data: JSONDict = {"id": self.id, "username": self.username, "first_name": self.first_name}
@@ -11559,3 +11887,7 @@ CHAT_ACTIVITY_TIMEOUT` seconds.
"""Alias for :meth:`remove_user_verification`"""
getMyStarBalance = get_my_star_balance
"""Alias for :meth:`get_my_star_balance`"""
approveSuggestedPost = approve_suggested_post
"""Alias for :meth:`approve_suggested_post`"""
declineSuggestedPost = decline_suggested_post
"""Alias for :meth:`decline_suggested_post`"""
+1
View File
@@ -18,6 +18,7 @@
# along with this program. If not, see [http://www.gnu.org/licenses/].
# pylint: disable=redefined-builtin
"""This module contains objects representing Telegram bot command scopes."""
from typing import TYPE_CHECKING, Final, Optional, Union
from telegram import constants
+1
View File
@@ -17,6 +17,7 @@
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains two objects that represent a Telegram bots (short) description."""
from typing import Optional
from telegram._telegramobject import TelegramObject
+1
View File
@@ -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 represent a Telegram bots name."""
from typing import Final, Optional
from telegram import constants
+1
View File
@@ -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 the Telegram Business related classes."""
import datetime as dtm
from collections.abc import Sequence
from typing import TYPE_CHECKING, Optional
+5
View File
@@ -18,6 +18,7 @@
# along with this program. If not, see [http://www.gnu.org/licenses/].
# pylint: disable=redefined-builtin
"""This module contains an object that represents a Telegram CallbackQuery"""
from collections.abc import Sequence
from typing import TYPE_CHECKING, Final, Optional, Union
@@ -41,6 +42,7 @@ if TYPE_CHECKING:
MessageEntity,
MessageId,
ReplyParameters,
SuggestedPostParameters,
)
@@ -870,6 +872,7 @@ class CallbackQuery(TelegramObject):
show_caption_above_media: Optional[bool] = None,
allow_paid_broadcast: Optional[bool] = None,
video_start_timestamp: Optional[int] = None,
suggested_post_parameters: Optional["SuggestedPostParameters"] = None,
*,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
reply_to_message_id: Optional[int] = None,
@@ -884,6 +887,7 @@ class CallbackQuery(TelegramObject):
await update.callback_query.message.copy(
from_chat_id=update.message.chat_id,
message_id=update.message.message_id,
direct_messages_topic_id=update.message.direct_messages_topic.topic_id,
*args,
**kwargs
)
@@ -919,6 +923,7 @@ class CallbackQuery(TelegramObject):
reply_parameters=reply_parameters,
show_caption_above_media=show_caption_above_media,
allow_paid_broadcast=allow_paid_broadcast,
suggested_post_parameters=suggested_post_parameters,
)
MAX_ANSWER_TEXT_LENGTH: Final[int] = (
+185 -9
View File
@@ -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 Chat."""
import datetime as dtm
from collections.abc import Sequence
from html import escape
@@ -39,6 +40,7 @@ from telegram._utils.types import (
ReplyMarkup,
TimePeriod,
)
from telegram._utils.usernames import get_full_name, get_link
from telegram.helpers import escape_markdown
from telegram.helpers import mention_html as helpers_mention_html
from telegram.helpers import mention_markdown as helpers_mention_markdown
@@ -69,6 +71,7 @@ if TYPE_CHECKING:
PhotoSize,
ReplyParameters,
Sticker,
SuggestedPostParameters,
UserChatBoosts,
Venue,
Video,
@@ -83,7 +86,16 @@ class _ChatBase(TelegramObject):
.. versionadded:: 21.3
"""
__slots__ = ("first_name", "id", "is_forum", "last_name", "title", "type", "username")
__slots__ = (
"first_name",
"id",
"is_direct_messages",
"is_forum",
"last_name",
"title",
"type",
"username",
)
def __init__(
self,
@@ -94,6 +106,7 @@ class _ChatBase(TelegramObject):
first_name: Optional[str] = None,
last_name: Optional[str] = None,
is_forum: Optional[bool] = None,
is_direct_messages: Optional[bool] = None,
*,
api_kwargs: Optional[JSONDict] = None,
):
@@ -107,6 +120,7 @@ class _ChatBase(TelegramObject):
self.first_name: Optional[str] = first_name
self.last_name: Optional[str] = last_name
self.is_forum: Optional[bool] = is_forum
self.is_direct_messages: Optional[bool] = is_direct_messages
self._id_attrs = (self.id,)
@@ -152,20 +166,14 @@ class _ChatBase(TelegramObject):
.. versionadded:: 13.2
"""
if not self.first_name:
return None
if self.last_name:
return f"{self.first_name} {self.last_name}"
return self.first_name
return get_full_name(self)
@property
def link(self) -> Optional[str]:
""":obj:`str`: Convenience property. If the chat has a :attr:`~Chat.username`, returns a
t.me link of the chat.
"""
if self.username:
return f"https://t.me/{self.username}"
return None
return get_link(self)
def mention_markdown(self, name: Optional[str] = None) -> str:
"""
@@ -608,6 +616,7 @@ class _ChatBase(TelegramObject):
can_post_stories: Optional[bool] = None,
can_edit_stories: Optional[bool] = None,
can_delete_stories: Optional[bool] = None,
can_manage_direct_messages: Optional[bool] = None,
*,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
@@ -658,6 +667,7 @@ class _ChatBase(TelegramObject):
can_post_stories=can_post_stories,
can_edit_stories=can_edit_stories,
can_delete_stories=can_delete_stories,
can_manage_direct_messages=can_manage_direct_messages,
)
async def restrict_member(
@@ -1022,6 +1032,8 @@ class _ChatBase(TelegramObject):
business_connection_id: Optional[str] = None,
message_effect_id: Optional[str] = None,
allow_paid_broadcast: Optional[bool] = None,
direct_messages_topic_id: Optional[int] = None,
suggested_post_parameters: Optional["SuggestedPostParameters"] = None,
*,
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
@@ -1064,6 +1076,8 @@ class _ChatBase(TelegramObject):
business_connection_id=business_connection_id,
message_effect_id=message_effect_id,
allow_paid_broadcast=allow_paid_broadcast,
direct_messages_topic_id=direct_messages_topic_id,
suggested_post_parameters=suggested_post_parameters,
)
async def delete_message(
@@ -1142,6 +1156,7 @@ class _ChatBase(TelegramObject):
business_connection_id: Optional[str] = None,
message_effect_id: Optional[str] = None,
allow_paid_broadcast: Optional[bool] = None,
direct_messages_topic_id: Optional[int] = None,
*,
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
@@ -1185,6 +1200,7 @@ class _ChatBase(TelegramObject):
business_connection_id=business_connection_id,
message_effect_id=message_effect_id,
allow_paid_broadcast=allow_paid_broadcast,
direct_messages_topic_id=direct_messages_topic_id,
)
async def send_chat_action(
@@ -1240,6 +1256,8 @@ class _ChatBase(TelegramObject):
message_effect_id: Optional[str] = None,
allow_paid_broadcast: Optional[bool] = None,
show_caption_above_media: Optional[bool] = None,
direct_messages_topic_id: Optional[int] = None,
suggested_post_parameters: Optional["SuggestedPostParameters"] = None,
*,
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
@@ -1284,6 +1302,8 @@ class _ChatBase(TelegramObject):
message_effect_id=message_effect_id,
allow_paid_broadcast=allow_paid_broadcast,
show_caption_above_media=show_caption_above_media,
direct_messages_topic_id=direct_messages_topic_id,
suggested_post_parameters=suggested_post_parameters,
)
async def send_contact(
@@ -1300,6 +1320,8 @@ class _ChatBase(TelegramObject):
business_connection_id: Optional[str] = None,
message_effect_id: Optional[str] = None,
allow_paid_broadcast: Optional[bool] = None,
direct_messages_topic_id: Optional[int] = None,
suggested_post_parameters: Optional["SuggestedPostParameters"] = None,
*,
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
@@ -1342,6 +1364,8 @@ class _ChatBase(TelegramObject):
business_connection_id=business_connection_id,
message_effect_id=message_effect_id,
allow_paid_broadcast=allow_paid_broadcast,
direct_messages_topic_id=direct_messages_topic_id,
suggested_post_parameters=suggested_post_parameters,
)
async def send_audio(
@@ -1362,6 +1386,8 @@ class _ChatBase(TelegramObject):
business_connection_id: Optional[str] = None,
message_effect_id: Optional[str] = None,
allow_paid_broadcast: Optional[bool] = None,
direct_messages_topic_id: Optional[int] = None,
suggested_post_parameters: Optional["SuggestedPostParameters"] = None,
*,
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
@@ -1408,6 +1434,8 @@ class _ChatBase(TelegramObject):
business_connection_id=business_connection_id,
message_effect_id=message_effect_id,
allow_paid_broadcast=allow_paid_broadcast,
direct_messages_topic_id=direct_messages_topic_id,
suggested_post_parameters=suggested_post_parameters,
)
async def send_document(
@@ -1426,6 +1454,8 @@ class _ChatBase(TelegramObject):
business_connection_id: Optional[str] = None,
message_effect_id: Optional[str] = None,
allow_paid_broadcast: Optional[bool] = None,
direct_messages_topic_id: Optional[int] = None,
suggested_post_parameters: Optional["SuggestedPostParameters"] = None,
*,
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
@@ -1470,6 +1500,8 @@ class _ChatBase(TelegramObject):
business_connection_id=business_connection_id,
message_effect_id=message_effect_id,
allow_paid_broadcast=allow_paid_broadcast,
direct_messages_topic_id=direct_messages_topic_id,
suggested_post_parameters=suggested_post_parameters,
)
async def send_checklist(
@@ -1531,6 +1563,8 @@ class _ChatBase(TelegramObject):
business_connection_id: Optional[str] = None,
message_effect_id: Optional[str] = None,
allow_paid_broadcast: Optional[bool] = None,
direct_messages_topic_id: Optional[int] = None,
suggested_post_parameters: Optional["SuggestedPostParameters"] = None,
*,
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
@@ -1568,6 +1602,8 @@ class _ChatBase(TelegramObject):
business_connection_id=business_connection_id,
message_effect_id=message_effect_id,
allow_paid_broadcast=allow_paid_broadcast,
direct_messages_topic_id=direct_messages_topic_id,
suggested_post_parameters=suggested_post_parameters,
)
async def send_game(
@@ -1650,6 +1686,8 @@ class _ChatBase(TelegramObject):
reply_parameters: Optional["ReplyParameters"] = None,
message_effect_id: Optional[str] = None,
allow_paid_broadcast: Optional[bool] = None,
direct_messages_topic_id: Optional[int] = None,
suggested_post_parameters: Optional["SuggestedPostParameters"] = None,
*,
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
@@ -1716,6 +1754,8 @@ class _ChatBase(TelegramObject):
reply_parameters=reply_parameters,
message_effect_id=message_effect_id,
allow_paid_broadcast=allow_paid_broadcast,
direct_messages_topic_id=direct_messages_topic_id,
suggested_post_parameters=suggested_post_parameters,
)
async def send_location(
@@ -1734,6 +1774,8 @@ class _ChatBase(TelegramObject):
business_connection_id: Optional[str] = None,
message_effect_id: Optional[str] = None,
allow_paid_broadcast: Optional[bool] = None,
direct_messages_topic_id: Optional[int] = None,
suggested_post_parameters: Optional["SuggestedPostParameters"] = None,
*,
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
@@ -1778,6 +1820,8 @@ class _ChatBase(TelegramObject):
business_connection_id=business_connection_id,
message_effect_id=message_effect_id,
allow_paid_broadcast=allow_paid_broadcast,
direct_messages_topic_id=direct_messages_topic_id,
suggested_post_parameters=suggested_post_parameters,
)
async def send_animation(
@@ -1800,6 +1844,8 @@ class _ChatBase(TelegramObject):
message_effect_id: Optional[str] = None,
allow_paid_broadcast: Optional[bool] = None,
show_caption_above_media: Optional[bool] = None,
direct_messages_topic_id: Optional[int] = None,
suggested_post_parameters: Optional["SuggestedPostParameters"] = None,
*,
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
@@ -1848,6 +1894,8 @@ class _ChatBase(TelegramObject):
message_effect_id=message_effect_id,
allow_paid_broadcast=allow_paid_broadcast,
show_caption_above_media=show_caption_above_media,
direct_messages_topic_id=direct_messages_topic_id,
suggested_post_parameters=suggested_post_parameters,
)
async def send_sticker(
@@ -1862,6 +1910,8 @@ class _ChatBase(TelegramObject):
business_connection_id: Optional[str] = None,
message_effect_id: Optional[str] = None,
allow_paid_broadcast: Optional[bool] = None,
direct_messages_topic_id: Optional[int] = None,
suggested_post_parameters: Optional["SuggestedPostParameters"] = None,
*,
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
@@ -1900,6 +1950,8 @@ class _ChatBase(TelegramObject):
business_connection_id=business_connection_id,
message_effect_id=message_effect_id,
allow_paid_broadcast=allow_paid_broadcast,
direct_messages_topic_id=direct_messages_topic_id,
suggested_post_parameters=suggested_post_parameters,
)
async def send_venue(
@@ -1920,6 +1972,8 @@ class _ChatBase(TelegramObject):
business_connection_id: Optional[str] = None,
message_effect_id: Optional[str] = None,
allow_paid_broadcast: Optional[bool] = None,
direct_messages_topic_id: Optional[int] = None,
suggested_post_parameters: Optional["SuggestedPostParameters"] = None,
*,
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
@@ -1966,6 +2020,8 @@ class _ChatBase(TelegramObject):
business_connection_id=business_connection_id,
message_effect_id=message_effect_id,
allow_paid_broadcast=allow_paid_broadcast,
direct_messages_topic_id=direct_messages_topic_id,
suggested_post_parameters=suggested_post_parameters,
)
async def send_video(
@@ -1991,6 +2047,8 @@ class _ChatBase(TelegramObject):
show_caption_above_media: Optional[bool] = None,
cover: Optional[FileInput] = None,
start_timestamp: Optional[int] = None,
direct_messages_topic_id: Optional[int] = None,
suggested_post_parameters: Optional["SuggestedPostParameters"] = None,
*,
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
@@ -2042,6 +2100,8 @@ class _ChatBase(TelegramObject):
message_effect_id=message_effect_id,
allow_paid_broadcast=allow_paid_broadcast,
show_caption_above_media=show_caption_above_media,
direct_messages_topic_id=direct_messages_topic_id,
suggested_post_parameters=suggested_post_parameters,
)
async def send_video_note(
@@ -2058,6 +2118,8 @@ class _ChatBase(TelegramObject):
business_connection_id: Optional[str] = None,
message_effect_id: Optional[str] = None,
allow_paid_broadcast: Optional[bool] = None,
direct_messages_topic_id: Optional[int] = None,
suggested_post_parameters: Optional["SuggestedPostParameters"] = None,
*,
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
@@ -2100,6 +2162,8 @@ class _ChatBase(TelegramObject):
business_connection_id=business_connection_id,
message_effect_id=message_effect_id,
allow_paid_broadcast=allow_paid_broadcast,
direct_messages_topic_id=direct_messages_topic_id,
suggested_post_parameters=suggested_post_parameters,
)
async def send_voice(
@@ -2117,6 +2181,8 @@ class _ChatBase(TelegramObject):
business_connection_id: Optional[str] = None,
message_effect_id: Optional[str] = None,
allow_paid_broadcast: Optional[bool] = None,
direct_messages_topic_id: Optional[int] = None,
suggested_post_parameters: Optional["SuggestedPostParameters"] = None,
*,
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
@@ -2160,6 +2226,8 @@ class _ChatBase(TelegramObject):
business_connection_id=business_connection_id,
message_effect_id=message_effect_id,
allow_paid_broadcast=allow_paid_broadcast,
direct_messages_topic_id=direct_messages_topic_id,
suggested_post_parameters=suggested_post_parameters,
)
async def send_poll(
@@ -2253,6 +2321,8 @@ class _ChatBase(TelegramObject):
show_caption_above_media: Optional[bool] = None,
allow_paid_broadcast: Optional[bool] = None,
video_start_timestamp: Optional[int] = None,
direct_messages_topic_id: Optional[int] = None,
suggested_post_parameters: Optional["SuggestedPostParameters"] = None,
*,
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
@@ -2296,6 +2366,8 @@ class _ChatBase(TelegramObject):
message_thread_id=message_thread_id,
show_caption_above_media=show_caption_above_media,
allow_paid_broadcast=allow_paid_broadcast,
direct_messages_topic_id=direct_messages_topic_id,
suggested_post_parameters=suggested_post_parameters,
)
async def copy_message(
@@ -2313,6 +2385,8 @@ class _ChatBase(TelegramObject):
show_caption_above_media: Optional[bool] = None,
allow_paid_broadcast: Optional[bool] = None,
video_start_timestamp: Optional[int] = None,
direct_messages_topic_id: Optional[int] = None,
suggested_post_parameters: Optional["SuggestedPostParameters"] = None,
*,
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
@@ -2356,6 +2430,8 @@ class _ChatBase(TelegramObject):
message_thread_id=message_thread_id,
show_caption_above_media=show_caption_above_media,
allow_paid_broadcast=allow_paid_broadcast,
direct_messages_topic_id=direct_messages_topic_id,
suggested_post_parameters=suggested_post_parameters,
)
async def send_copies(
@@ -2366,6 +2442,7 @@ class _ChatBase(TelegramObject):
protect_content: ODVInput[bool] = DEFAULT_NONE,
message_thread_id: Optional[int] = None,
remove_caption: Optional[bool] = None,
direct_messages_topic_id: Optional[int] = None,
*,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
@@ -2401,6 +2478,7 @@ class _ChatBase(TelegramObject):
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
api_kwargs=api_kwargs,
direct_messages_topic_id=direct_messages_topic_id,
)
async def copy_messages(
@@ -2411,6 +2489,7 @@ class _ChatBase(TelegramObject):
protect_content: ODVInput[bool] = DEFAULT_NONE,
message_thread_id: Optional[int] = None,
remove_caption: Optional[bool] = None,
direct_messages_topic_id: Optional[int] = None,
*,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
@@ -2446,6 +2525,7 @@ class _ChatBase(TelegramObject):
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
api_kwargs=api_kwargs,
direct_messages_topic_id=direct_messages_topic_id,
)
async def forward_from(
@@ -2456,6 +2536,8 @@ class _ChatBase(TelegramObject):
protect_content: ODVInput[bool] = DEFAULT_NONE,
message_thread_id: Optional[int] = None,
video_start_timestamp: Optional[int] = None,
direct_messages_topic_id: Optional[int] = None,
suggested_post_parameters: Optional["SuggestedPostParameters"] = None,
*,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
@@ -2490,6 +2572,8 @@ class _ChatBase(TelegramObject):
api_kwargs=api_kwargs,
protect_content=protect_content,
message_thread_id=message_thread_id,
direct_messages_topic_id=direct_messages_topic_id,
suggested_post_parameters=suggested_post_parameters,
)
async def forward_to(
@@ -2500,6 +2584,8 @@ class _ChatBase(TelegramObject):
protect_content: ODVInput[bool] = DEFAULT_NONE,
message_thread_id: Optional[int] = None,
video_start_timestamp: Optional[int] = None,
direct_messages_topic_id: Optional[int] = None,
suggested_post_parameters: Optional["SuggestedPostParameters"] = None,
*,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
@@ -2535,6 +2621,8 @@ class _ChatBase(TelegramObject):
api_kwargs=api_kwargs,
protect_content=protect_content,
message_thread_id=message_thread_id,
direct_messages_topic_id=direct_messages_topic_id,
suggested_post_parameters=suggested_post_parameters,
)
async def forward_messages_from(
@@ -2544,6 +2632,7 @@ class _ChatBase(TelegramObject):
disable_notification: ODVInput[bool] = DEFAULT_NONE,
protect_content: ODVInput[bool] = DEFAULT_NONE,
message_thread_id: Optional[int] = None,
direct_messages_topic_id: Optional[int] = None,
*,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
@@ -2578,6 +2667,7 @@ class _ChatBase(TelegramObject):
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
api_kwargs=api_kwargs,
direct_messages_topic_id=direct_messages_topic_id,
)
async def forward_messages_to(
@@ -2587,6 +2677,7 @@ class _ChatBase(TelegramObject):
disable_notification: ODVInput[bool] = DEFAULT_NONE,
protect_content: ODVInput[bool] = DEFAULT_NONE,
message_thread_id: Optional[int] = None,
direct_messages_topic_id: Optional[int] = None,
*,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
@@ -2621,6 +2712,7 @@ class _ChatBase(TelegramObject):
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
api_kwargs=api_kwargs,
direct_messages_topic_id=direct_messages_topic_id,
)
async def export_invite_link(
@@ -3460,6 +3552,9 @@ class _ChatBase(TelegramObject):
business_connection_id: Optional[str] = None,
payload: Optional[str] = None,
allow_paid_broadcast: Optional[bool] = None,
direct_messages_topic_id: Optional[int] = None,
suggested_post_parameters: Optional["SuggestedPostParameters"] = None,
message_thread_id: Optional[int] = None,
*,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
reply_to_message_id: Optional[int] = None,
@@ -3503,6 +3598,9 @@ class _ChatBase(TelegramObject):
business_connection_id=business_connection_id,
payload=payload,
allow_paid_broadcast=allow_paid_broadcast,
direct_messages_topic_id=direct_messages_topic_id,
suggested_post_parameters=suggested_post_parameters,
message_thread_id=message_thread_id,
)
async def send_gift(
@@ -3686,6 +3784,76 @@ class _ChatBase(TelegramObject):
api_kwargs=api_kwargs,
)
async def approve_suggested_post(
self,
message_id: int,
send_date: Optional[Union[int, dtm.datetime]] = 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,
) -> bool:
"""
Shortcut for::
await bot.approve_suggested_post(chat_id=update.effective_chat.id, *args, **kwargs)
For the documentation of the arguments, please see
:meth:`telegram.Bot.approve_suggested_post`.
.. versionadded:: 22.4
Returns:
:obj:`bool`: On success, :obj:`True` is returned.
"""
return await self.get_bot().approve_suggested_post(
chat_id=self.id,
message_id=message_id,
send_date=send_date,
read_timeout=read_timeout,
write_timeout=write_timeout,
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
api_kwargs=api_kwargs,
)
async def decline_suggested_post(
self,
message_id: int,
comment: 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,
) -> bool:
"""
Shortcut for::
await bot.decline_suggested_post(chat_id=update.effective_chat.id, *args, **kwargs)
For the documentation of the arguments, please see
:meth:`telegram.Bot.decline_suggested_post`.
.. versionadded:: 22.4
Returns:
:obj:`bool`: On success, :obj:`True` is returned.
"""
return await self.get_bot().decline_suggested_post(
chat_id=self.id,
message_id=message_id,
comment=comment,
read_timeout=read_timeout,
write_timeout=write_timeout,
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
api_kwargs=api_kwargs,
)
class Chat(_ChatBase):
"""This object represents a chat.
@@ -3723,6 +3891,10 @@ class Chat(_ChatBase):
(has topics_ enabled).
.. versionadded:: 20.0
is_direct_messages (:obj:`bool`, optional): :obj:`True`, if the chat is the direct messages
chat of a channel.
.. versionadded:: 22.4
Attributes:
id (:obj:`int`): Unique identifier for this chat.
@@ -3737,6 +3909,10 @@ class Chat(_ChatBase):
(has topics_ enabled).
.. versionadded:: 20.0
is_direct_messages (:obj:`bool`): Optional. :obj:`True`, if the chat is the direct messages
chat of a channel.
.. versionadded:: 22.4
.. _topics: https://telegram.org/blog/topics-in-groups-collectible-usernames#topics-in-groups
"""
+19 -2
View File
@@ -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 the class which represents a Telegram ChatAdministratorRights."""
from typing import Optional
from telegram._telegramobject import TelegramObject
@@ -31,8 +32,8 @@ class ChatAdministratorRights(TelegramObject):
:attr:`can_delete_messages`, :attr:`can_manage_video_chats`, :attr:`can_restrict_members`,
:attr:`can_promote_members`, :attr:`can_change_info`, :attr:`can_invite_users`,
:attr:`can_post_messages`, :attr:`can_edit_messages`, :attr:`can_pin_messages`,
:attr:`can_manage_topics`, :attr:`can_post_stories`, :attr:`can_delete_stories`, and
:attr:`can_edit_stories` are equal.
:attr:`can_manage_topics`, :attr:`can_post_stories`, :attr:`can_delete_stories`,
:attr:`can_edit_stories` and :attr:`can_manage_direct_messages` are equal.
.. versionadded:: 20.0
@@ -49,6 +50,10 @@ class ChatAdministratorRights(TelegramObject):
and :attr:`can_delete_stories` is now required. Thus, the order of arguments had to be
changed.
.. versionchanged:: 22.4
:attr:`can_manage_direct_messages` is considered as well when comparing objects of
this type in terms of equality.
Args:
is_anonymous (:obj:`bool`): :obj:`True`, if the user's presence in the chat is hidden.
can_manage_chat (:obj:`bool`): :obj:`True`, if the administrator can access the chat event
@@ -97,6 +102,10 @@ class ChatAdministratorRights(TelegramObject):
to create, rename, close, and reopen forum topics; for supergroups only.
.. versionadded:: 20.0
can_manage_direct_messages (:obj:`bool`, optional): :obj:`True`, if the administrator can
manage direct messages of the channel and decline suggested posts; for channels only.
.. versionadded:: 22.4
Attributes:
is_anonymous (:obj:`bool`): :obj:`True`, if the user's presence in the chat is hidden.
@@ -146,6 +155,10 @@ class ChatAdministratorRights(TelegramObject):
to create, rename, close, and reopen forum topics; for supergroups only.
.. versionadded:: 20.0
can_manage_direct_messages (:obj:`bool`): Optional. :obj:`True`, if the administrator can
manage direct messages of the channel and decline suggested posts; for channels only.
.. versionadded:: 22.4
"""
__slots__ = (
@@ -156,6 +169,7 @@ class ChatAdministratorRights(TelegramObject):
"can_edit_stories",
"can_invite_users",
"can_manage_chat",
"can_manage_direct_messages",
"can_manage_topics",
"can_manage_video_chats",
"can_pin_messages",
@@ -183,6 +197,7 @@ class ChatAdministratorRights(TelegramObject):
can_edit_messages: Optional[bool] = None,
can_pin_messages: Optional[bool] = None,
can_manage_topics: Optional[bool] = None,
can_manage_direct_messages: Optional[bool] = None,
*,
api_kwargs: Optional[JSONDict] = None,
) -> None:
@@ -204,6 +219,7 @@ class ChatAdministratorRights(TelegramObject):
self.can_edit_messages: Optional[bool] = can_edit_messages
self.can_pin_messages: Optional[bool] = can_pin_messages
self.can_manage_topics: Optional[bool] = can_manage_topics
self.can_manage_direct_messages: Optional[bool] = can_manage_direct_messages
self._id_attrs = (
self.is_anonymous,
@@ -221,6 +237,7 @@ class ChatAdministratorRights(TelegramObject):
self.can_post_stories,
self.can_edit_stories,
self.can_delete_stories,
self.can_manage_direct_messages,
)
self._freeze()
+1
View File
@@ -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 objects related to chat backgrounds."""
from collections.abc import Sequence
from typing import TYPE_CHECKING, Final, Optional
+1
View File
@@ -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 the classes that represent Telegram ChatBoosts."""
import datetime as dtm
from collections.abc import Sequence
from typing import TYPE_CHECKING, Final, Optional
+23
View File
@@ -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 ChatFullInfo."""
import datetime as dtm
from collections.abc import Sequence
from typing import TYPE_CHECKING, Optional, Union
@@ -223,6 +224,14 @@ class ChatFullInfo(_ChatBase):
sent or forwarded to the channel chat. The field is available only for channel chats.
.. versionadded:: 21.4
is_direct_messages (:obj:`bool`, optional): :obj:`True`, if the chat is the direct messages
chat of a channel.
.. versionadded:: 22.4
parent_chat (:obj:`telegram.Chat`, optional): Information about the corresponding channel
chat; for direct messages chats only.
.. versionadded:: 22.4
Attributes:
id (:obj:`int`): Unique identifier for this chat.
@@ -387,6 +396,14 @@ class ChatFullInfo(_ChatBase):
sent or forwarded to the channel chat. The field is available only for channel chats.
.. versionadded:: 21.4
is_direct_messages (:obj:`bool`): Optional. :obj:`True`, if the chat is the direct messages
chat of a channel.
.. versionadded:: 22.4
parent_chat (:obj:`telegram.Chat`): Optional. Information about the corresponding channel
chat; for direct messages chats only.
.. versionadded:: 22.4
.. _accent colors: https://core.telegram.org/bots/api#accent-colors
.. _topics: https://telegram.org/blog/topics-in-groups-collectible-usernames#topics-in-groups
@@ -423,6 +440,7 @@ class ChatFullInfo(_ChatBase):
"linked_chat_id",
"location",
"max_reaction_count",
"parent_chat",
"permissions",
"personal_chat",
"photo",
@@ -480,6 +498,8 @@ class ChatFullInfo(_ChatBase):
linked_chat_id: Optional[int] = None,
location: Optional[ChatLocation] = None,
can_send_paid_media: Optional[bool] = None,
is_direct_messages: Optional[bool] = None,
parent_chat: Optional[Chat] = None,
*,
api_kwargs: Optional[JSONDict] = None,
):
@@ -491,6 +511,7 @@ class ChatFullInfo(_ChatBase):
first_name=first_name,
last_name=last_name,
is_forum=is_forum,
is_direct_messages=is_direct_messages,
api_kwargs=api_kwargs,
)
# Required and unique to this class-
@@ -545,6 +566,7 @@ class ChatFullInfo(_ChatBase):
self.business_opening_hours: Optional[BusinessOpeningHours] = business_opening_hours
self.can_send_paid_media: Optional[bool] = can_send_paid_media
self.accepted_gift_types: AcceptedGiftTypes = accepted_gift_types
self.parent_chat: Optional[Chat] = parent_chat
@property
def slow_mode_delay(self) -> Optional[Union[int, dtm.timedelta]]:
@@ -595,5 +617,6 @@ class ChatFullInfo(_ChatBase):
data["business_opening_hours"] = de_json_optional(
data.get("business_opening_hours"), BusinessOpeningHours, bot
)
data["parent_chat"] = de_json_optional(data.get("parent_chat"), Chat, bot)
return super().de_json(data=data, bot=bot)
+1
View File
@@ -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 an invite link for a chat."""
import datetime as dtm
from typing import TYPE_CHECKING, Optional, Union
+1
View File
@@ -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 ChatJoinRequest."""
import datetime as dtm
from typing import TYPE_CHECKING, Optional
+11
View File
@@ -253,6 +253,10 @@ class ChatMemberAdministrator(ChatMember):
.. versionadded:: 20.0
custom_title (:obj:`str`, optional): Custom title for this user.
can_manage_direct_messages (:obj:`bool`, optional): :obj:`True`, if the administrator can
manage direct messages of the channel and decline suggested posts; for channels only.
.. versionadded:: 22.4
Attributes:
status (:obj:`str`): The member's status in the chat,
@@ -313,6 +317,10 @@ class ChatMemberAdministrator(ChatMember):
.. versionadded:: 20.0
custom_title (:obj:`str`): Optional. Custom title for this user.
can_manage_direct_messages (:obj:`bool`, optional): :obj:`True`, if the administrator can
manage direct messages of the channel and decline suggested posts; for channels only.
.. versionadded:: 22.4
"""
__slots__ = (
@@ -324,6 +332,7 @@ class ChatMemberAdministrator(ChatMember):
"can_edit_stories",
"can_invite_users",
"can_manage_chat",
"can_manage_direct_messages",
"can_manage_topics",
"can_manage_video_chats",
"can_pin_messages",
@@ -355,6 +364,7 @@ class ChatMemberAdministrator(ChatMember):
can_pin_messages: Optional[bool] = None,
can_manage_topics: Optional[bool] = None,
custom_title: Optional[str] = None,
can_manage_direct_messages: Optional[bool] = None,
*,
api_kwargs: Optional[JSONDict] = None,
):
@@ -378,6 +388,7 @@ class ChatMemberAdministrator(ChatMember):
self.can_pin_messages: Optional[bool] = can_pin_messages
self.can_manage_topics: Optional[bool] = can_manage_topics
self.custom_title: Optional[str] = custom_title
self.can_manage_direct_messages: Optional[bool] = can_manage_direct_messages
class ChatMemberMember(ChatMember):
+1
View File
@@ -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 ChatMemberUpdated."""
import datetime as dtm
from typing import TYPE_CHECKING, Optional, Union
+1
View File
@@ -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 ChatPermission."""
from typing import TYPE_CHECKING, Optional
from telegram._telegramobject import TelegramObject
+2 -1
View File
@@ -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 objects related to Telegram checklists."""
import datetime as dtm
from collections.abc import Sequence
from typing import TYPE_CHECKING, Optional
@@ -39,7 +40,7 @@ class ChecklistTask(TelegramObject):
Describes a task in a checklist.
Objects of this class are comparable in terms of equality.
Two objects of this class are considered equal, if all their :attr:`id` is equal.
Two objects of this class are considered equal, if their :attr:`id` is equal.
.. versionadded:: 22.3
+1
View File
@@ -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 CopyTextButton."""
from typing import Optional
from telegram._telegramobject import TelegramObject
+1
View File
@@ -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 Dice."""
from typing import Final, Optional
from telegram import constants
@@ -18,7 +18,6 @@
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains an object that represents a Direct Message Price."""
from typing import Optional
from telegram._telegramobject import TelegramObject
+86
View File
@@ -0,0 +1,86 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2025
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser Public License for more details.
#
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains the DirectMessagesTopic class."""
from typing import TYPE_CHECKING, Optional
from telegram._telegramobject import TelegramObject
from telegram._user import User
from telegram._utils.argumentparsing import de_json_optional
from telegram._utils.types import JSONDict
if TYPE_CHECKING:
from telegram._bot import Bot
class DirectMessagesTopic(TelegramObject):
"""
This class represents a topic for direct messages in a chat.
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`topic_id` and :attr:`user` is equal.
.. versionadded:: 22.4
Args:
topic_id (:obj:`int`): Unique identifier of the topic. This number may have more than 32
significant bits and some programming languages may have difficulty/silent defects in
interpreting it. But it has at most 52 significant bits, so a 64-bit integer or
double-precision float type are safe for storing this identifier.
user (:class:`telegram.User`, optional): Information about the user that created the topic.
.. hint::
According to Telegram, this field is always present as of Bot API 9.2.
Attributes:
topic_id (:obj:`int`): Unique identifier of the topic. This number may have more than 32
significant bits and some programming languages may have difficulty/silent defects in
interpreting it. But it has at most 52 significant bits, so a 64-bit integer or
double-precision float type are safe for storing this identifier.
user (:class:`telegram.User`): Optional. Information about the user that created the topic.
.. hint::
According to Telegram, this field is always present as of Bot API 9.2.
"""
__slots__ = ("topic_id", "user")
def __init__(
self, topic_id: int, user: Optional[User] = None, *, api_kwargs: Optional[JSONDict] = None
):
super().__init__(api_kwargs=api_kwargs)
# Required:
self.topic_id: int = topic_id
# Optionals:
self.user: Optional[User] = user
self._id_attrs = (self.topic_id, self.user)
self._freeze()
@classmethod
def de_json(cls, data: JSONDict, bot: Optional["Bot"] = None) -> "DirectMessagesTopic":
"""See :meth:`telegram.TelegramObject.de_json`."""
data = cls._parse_data(data)
data["user"] = de_json_optional(data.get("user"), User, bot)
return super().de_json(data=data, bot=bot)

Some files were not shown because too many files have changed in this diff Show More