mirror of
https://github.com/python-telegram-bot/python-telegram-bot.git
synced 2026-06-26 11:14:50 +00:00
Compare commits
49 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| df07148e2d | |||
| 2d2cede442 | |||
| 08e223ba90 | |||
| 01d643913e | |||
| 755945172d | |||
| 24b4de9f10 | |||
| 76bfe8ceff | |||
| b498786d7c | |||
| bfe30048e8 | |||
| e25c523b69 | |||
| 67e7468366 | |||
| 11007c1715 | |||
| d6e95f1974 | |||
| de28f177bd | |||
| 63104ac0b3 | |||
| 22419c0464 | |||
| 42276338b1 | |||
| 5f547f3725 | |||
| 8e7220e5db | |||
| 977d56ab43 | |||
| 306cc64170 | |||
| 42955ecddf | |||
| 67869693a7 | |||
| 6ded9cc25c | |||
| 5e0bcfbcc6 | |||
| a17a4c6c8f | |||
| dc13b69dac | |||
| 349baa0202 | |||
| 5e24765bbc | |||
| e10d933fde | |||
| 2175af6abc | |||
| ca4e4c6280 | |||
| d2cabcaa74 | |||
| 076955d04d | |||
| c1041655f6 | |||
| 298c5fab3b | |||
| 3013870c1f | |||
| 5e924014de | |||
| f792102212 | |||
| 72e357a780 | |||
| 72c3eb857b | |||
| 1f7efe4519 | |||
| e47d18c9ec | |||
| 65bbea780a | |||
| 23ed0880d2 | |||
| a299867b1b | |||
| be8f4f7aad | |||
| ea8089ad3e | |||
| d917404de1 |
@@ -0,0 +1,7 @@
|
||||
# .git-blame-ignore-revs
|
||||
# Use locally as `git blame file.py --ignore-revs-file .git-blame-ignore-revs`
|
||||
# or configure git to always use it: `git config blame.ignoreRevsFile .git-blame-ignore-revs`
|
||||
# First migration to code style Black (#2122)
|
||||
264b2c9c72691c5937b80e84e061c52dd2d8861a
|
||||
# Use Black more extensively (#2972)
|
||||
950d9a0751d79b92d78ea44344ce3e3c5b3948f9
|
||||
@@ -263,19 +263,19 @@ break the API classes. For example:
|
||||
self.last_name = last_name
|
||||
|
||||
|
||||
.. _`Code of Conduct`: https://www.python.org/psf/codeofconduct/
|
||||
.. _`Code of Conduct`: https://www.python.org/psf/conduct/
|
||||
.. _`issue tracker`: https://github.com/python-telegram-bot/python-telegram-bot/issues
|
||||
.. _`Telegram group`: https://telegram.me/pythontelegrambotgroup
|
||||
.. _`PEP 8 Style Guide`: https://www.python.org/dev/peps/pep-0008/
|
||||
.. _`sphinx`: http://sphinx-doc.org
|
||||
.. _`Google Python Style Guide`: http://google.github.io/styleguide/pyguide.html
|
||||
.. _`PEP 8 Style Guide`: https://peps.python.org/pep-0008/
|
||||
.. _`sphinx`: https://www.sphinx-doc.org/en/master
|
||||
.. _`Google Python Style Guide`: https://google.github.io/styleguide/pyguide.html
|
||||
.. _`Google Python Style Docstrings`: https://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_google.html
|
||||
.. _AUTHORS.rst: ../AUTHORS.rst
|
||||
.. _AUTHORS.rst: https://github.com/python-telegram-bot/python-telegram-bot/blob/master/AUTHORS.rst
|
||||
.. _`MyPy`: https://mypy.readthedocs.io/en/stable/index.html
|
||||
.. _`here`: https://mypy.readthedocs.io/en/stable/cheat_sheet_py3.html
|
||||
.. _`Black`: https://black.readthedocs.io/en/stable/index.html
|
||||
.. _`popular editors`: https://black.readthedocs.io/en/stable/editor_integration.html
|
||||
.. _`RTD`: https://python-telegram-bot.readthedocs.io/
|
||||
.. _`RTD build`: https://python-telegram-bot.readthedocs.io/en/doc-fixes
|
||||
.. _`popular editors`: https://black.readthedocs.io/en/stable/integrations/editors.html
|
||||
.. _`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
|
||||
.. _`section`: #documenting
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
name: Check Links in Documentation
|
||||
on:
|
||||
schedule:
|
||||
# First day of month at 05:46 in every 2nd month
|
||||
- cron: '46 5 1 */2 *'
|
||||
|
||||
jobs:
|
||||
test-sphinx-build:
|
||||
name: test-sphinx-linkcheck
|
||||
runs-on: ${{matrix.os}}
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [3.7]
|
||||
os: [ubuntu-latest]
|
||||
fail-fast: False
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v3
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -W ignore -m pip install --upgrade pip
|
||||
python -W ignore -m pip install -r requirements.txt
|
||||
python -W ignore -m pip install -r requirements-dev.txt
|
||||
python -W ignore -m pip install -r docs/requirements-docs.txt
|
||||
- name: Check Links
|
||||
run: sphinx-build docs/source docs/build/html -W --keep-going -j auto -b linkcheck
|
||||
@@ -3,12 +3,10 @@ on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
- v14
|
||||
- doc-fixes
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- v14
|
||||
- doc-fixes
|
||||
|
||||
jobs:
|
||||
@@ -22,9 +20,6 @@ jobs:
|
||||
fail-fast: False
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Initialize vendored libs
|
||||
run:
|
||||
git submodule update --init --recursive
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v3
|
||||
with:
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
name: Warning maintainers
|
||||
on:
|
||||
pull_request_target:
|
||||
paths: examples/**
|
||||
permissions:
|
||||
pull-requests: write
|
||||
jobs:
|
||||
job:
|
||||
runs-on: ubuntu-latest
|
||||
name: about example change
|
||||
steps:
|
||||
- name: running the check
|
||||
uses: Poolitzer/notifier-action@master
|
||||
with:
|
||||
notify-message: Hey there. Relax, I am just a little warning for the maintainers to release directly after merging your PR, otherwise we have broken examples and people might get confused :)
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -9,10 +9,10 @@ jobs:
|
||||
lock:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: dessant/lock-threads@v2.0.1
|
||||
- uses: dessant/lock-threads@v3.0.0
|
||||
with:
|
||||
github-token: ${{ github.token }}
|
||||
issue-lock-inactive-days: '7'
|
||||
issue-inactive-days: '7'
|
||||
issue-lock-reason: ''
|
||||
pr-lock-inactive-days: '7'
|
||||
pr-inactive-days: '7'
|
||||
pr-lock-reason: ''
|
||||
|
||||
+14
-9
@@ -5,6 +5,9 @@
|
||||
ci:
|
||||
autofix_prs: false
|
||||
autoupdate_schedule: monthly
|
||||
# We currently only need this behavior on the v13.x branch were we have the vendored urllib
|
||||
# TODO: Remove once we discontinue v13
|
||||
submodules: true
|
||||
|
||||
repos:
|
||||
- repo: https://github.com/psf/black
|
||||
@@ -19,7 +22,7 @@ repos:
|
||||
hooks:
|
||||
- id: flake8
|
||||
- repo: https://github.com/PyCQA/pylint
|
||||
rev: v2.13.8
|
||||
rev: v2.13.9
|
||||
hooks:
|
||||
- id: pylint
|
||||
files: ^(telegram|examples)/.*\.py$
|
||||
@@ -30,13 +33,13 @@ repos:
|
||||
- --jobs=0
|
||||
|
||||
additional_dependencies:
|
||||
- httpx~=0.22.0
|
||||
- httpx~=0.23.0
|
||||
- tornado~=6.1
|
||||
- APScheduler~=3.9.1
|
||||
- cachetools~=5.0.0
|
||||
- cachetools~=5.2.0
|
||||
- . # this basically does `pip install -e .`
|
||||
- repo: https://github.com/pre-commit/mirrors-mypy
|
||||
rev: v0.950
|
||||
rev: v0.961
|
||||
hooks:
|
||||
- id: mypy
|
||||
name: mypy-ptb
|
||||
@@ -46,10 +49,10 @@ repos:
|
||||
- types-pytz
|
||||
- types-cryptography
|
||||
- types-cachetools
|
||||
- httpx~=0.22.0
|
||||
- httpx~=0.23.0
|
||||
- tornado~=6.1
|
||||
- APScheduler~=3.9.1
|
||||
- cachetools~=5.0.0
|
||||
- cachetools~=5.2.0
|
||||
- . # this basically does `pip install -e .`
|
||||
- id: mypy
|
||||
name: mypy-examples
|
||||
@@ -60,10 +63,10 @@ repos:
|
||||
additional_dependencies:
|
||||
- tornado~=6.1
|
||||
- APScheduler~=3.9.1
|
||||
- cachetools~=5.0.0
|
||||
- cachetools~=5.2.0
|
||||
- . # this basically does `pip install -e .`
|
||||
- repo: https://github.com/asottile/pyupgrade
|
||||
rev: v2.32.0
|
||||
rev: v2.34.0
|
||||
hooks:
|
||||
- id: pyupgrade
|
||||
files: ^(telegram|examples|tests)/.*\.py$
|
||||
@@ -74,4 +77,6 @@ repos:
|
||||
hooks:
|
||||
- id: isort
|
||||
name: isort
|
||||
args: ["--diff"] # -diff will not apply the changes, just show them
|
||||
args:
|
||||
- --diff
|
||||
- --check
|
||||
|
||||
+5
-1
@@ -15,8 +15,12 @@ formats:
|
||||
|
||||
# Optionally set the version of Python and requirements required to build your docs
|
||||
python:
|
||||
version: 3
|
||||
install:
|
||||
- method: pip
|
||||
path: .
|
||||
- requirements: docs/requirements-docs.txt
|
||||
|
||||
build:
|
||||
os: ubuntu-20.04
|
||||
tools:
|
||||
python: "3" # latest stable cpython version
|
||||
|
||||
@@ -29,6 +29,7 @@ The following wonderful people contributed directly or indirectly to this projec
|
||||
- `Balduro <https://github.com/Balduro>`_
|
||||
- `Bibo-Joshi <https://github.com/Bibo-Joshi>`_
|
||||
- `bimmlerd <https://github.com/bimmlerd>`_
|
||||
- `cyc8 <https://github.com/cyc8>`_
|
||||
- `d-qoi <https://github.com/d-qoi>`_
|
||||
- `daimajia <https://github.com/daimajia>`_
|
||||
- `Daniel Reed <https://github.com/nmlorg>`_
|
||||
@@ -45,6 +46,7 @@ The following wonderful people contributed directly or indirectly to this projec
|
||||
- `Evan Haberecht <https://github.com/habereet>`_
|
||||
- `Evgeny Denisov <https://github.com/eIGato>`_
|
||||
- `evgfilim1 <https://github.com/evgfilim1>`_
|
||||
- `ExalFabu <https://github.com/ExalFabu>`_
|
||||
- `franciscod <https://github.com/franciscod>`_
|
||||
- `gamgi <https://github.com/gamgi>`_
|
||||
- `Gauthamram Ravichandran <https://github.com/GauthamramRavichandran>`_
|
||||
@@ -105,8 +107,10 @@ The following wonderful people contributed directly or indirectly to this projec
|
||||
- `Vorobjev Simon <https://github.com/simonvorobjev>`_
|
||||
- `Wagner Macedo <https://github.com/wagnerluis1982>`_
|
||||
- `wjt <https://github.com/wjt>`_
|
||||
- `Yaw Danso <https://github.com/dglitxh>`_
|
||||
- `zeroone2numeral2 <https://github.com/zeroone2numeral2>`_
|
||||
- `zeshuaro <https://github.com/zeshuaro>`_
|
||||
- `zpavloudis <https://github.com/zpavloudis>`_
|
||||
|
||||
|
||||
Please add yourself here alphabetically when you submit your first pull request.
|
||||
|
||||
+148
-4
@@ -2,6 +2,150 @@
|
||||
Changelog
|
||||
=========
|
||||
|
||||
Version 20.0a2
|
||||
==============
|
||||
*Released 2022-06-27*
|
||||
|
||||
This is the technical changelog for version 20.0a2. More elaborate release notes can be found in the news channel `@pythontelegrambotchannel <https://t.me/pythontelegrambotchannel>`_.
|
||||
|
||||
Major Changes
|
||||
-------------
|
||||
|
||||
- Full Support for API 6.1 (`#3112`_)
|
||||
|
||||
New Features
|
||||
------------
|
||||
|
||||
- Add Additional Shortcut Methods to ``Chat`` (`#3115`_)
|
||||
- Mermaid-based Example State Diagrams (`#3090`_)
|
||||
|
||||
Minor Changes, Documentation Improvements and CI
|
||||
------------------------------------------------
|
||||
|
||||
- Documentation Improvements (`#3103`_, `#3121`_, `#3098`_)
|
||||
- Stabilize CI (`#3119`_)
|
||||
- Bump ``pyupgrade`` from 2.32.1 to 2.34.0 (`#3096`_)
|
||||
- Bump ``furo`` from 2022.6.4 to 2022.6.4.1 (`#3095`_)
|
||||
- Bump ``mypy`` from 0.960 to 0.961 (`#3093`_)
|
||||
|
||||
.. _`#3112`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3112
|
||||
.. _`#3115`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3115
|
||||
.. _`#3090`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3090
|
||||
.. _`#3103`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3103
|
||||
.. _`#3121`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3121
|
||||
.. _`#3098`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3098
|
||||
.. _`#3119`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3119
|
||||
.. _`#3096`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3096
|
||||
.. _`#3095`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3095
|
||||
.. _`#3093`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3093
|
||||
|
||||
Version 20.0a1
|
||||
==============
|
||||
*Released 2022-06-09*
|
||||
|
||||
This is the technical changelog for version 20.0a1. More elaborate release notes can be found in the news channel `@pythontelegrambotchannel <https://t.me/pythontelegrambotchannel>`_.
|
||||
|
||||
Major Changes:
|
||||
--------------
|
||||
|
||||
- Drop Support for ``ujson`` and instead ``BaseRequest.parse_json_payload`` (`#3037`_, `#3072`_)
|
||||
- Drop ``InputFile.is_image`` (`#3053`_)
|
||||
- Drop Explicit Type conversions in ``__init__`` s (`#3056`_)
|
||||
- Handle List-Valued Attributes More Consistently (`#3057`_)
|
||||
- Split ``{Command, Prefix}Handler`` And Make Attributes Immutable (`#3045`_)
|
||||
- Align Behavior Of ``JobQueue.run_daily`` With ``cron`` (`#3046`_)
|
||||
- Make PTB Specific Keyword-Only Arguments for PTB Specific in Bot methods (`#3035`_)
|
||||
- Adjust Equality Comparisons to Fit Bot API 6.0 (`#3033`_)
|
||||
- Add Tuple Based Version Info (`#3030`_)- Improve Type Annotations for ``CallbackContext`` and Move Default Type Alias to ``ContextTypes.DEFAULT_TYPE`` (`#3017`_, `#3023`_)
|
||||
- Rename ``Job.context`` to ``Job.data`` (`#3028`_)
|
||||
- Rename ``Handler`` to ``BaseHandler`` (`#3019`_)
|
||||
|
||||
New Features:
|
||||
-------------
|
||||
|
||||
- Add ``Application.post_init`` (`#3078`_)
|
||||
- Add Arguments ``chat/user_id`` to ``CallbackContext`` And Example On Custom Webhook Setups (`#3059`_)
|
||||
- Add Convenience Property ``Message.id`` (`#3077`_)
|
||||
- Add Example for ``WebApp`` (`#3052`_)
|
||||
- Rename ``telegram.bot_api_version`` to ``telegram.__bot_api_version__`` (`#3030`_)
|
||||
|
||||
Bug Fixes:
|
||||
----------
|
||||
|
||||
- Fix Non-Blocking Entry Point in ``ConversationHandler`` (`#3068`_)
|
||||
- Escape Backslashes in ``escape_markdown`` (`#3055`_)
|
||||
|
||||
Dependencies:
|
||||
-------------
|
||||
|
||||
- Update ``httpx`` requirement from ~=0.22.0 to ~=0.23.0 (`#3069`_)
|
||||
- Update ``cachetools`` requirement from ~=5.0.0 to ~=5.2.0 (`#3058`_, `#3080`_)
|
||||
|
||||
Minor Changes, Documentation Improvements and CI:
|
||||
-------------------------------------------------
|
||||
|
||||
- Move Examples To Documentation (`#3089`_)
|
||||
- Documentation Improvements and Update Dependencies (`#3010`_, `#3007`_, `#3012`_, `#3067`_, `#3081`_, `#3082`_)
|
||||
- Improve Some Unit Tests (`#3026`_)
|
||||
- Update Code Quality dependencies (`#3070`_, `#3032`_,`#2998`_, `#2999`_)
|
||||
- Don't Set Signal Handlers On Windows By Default (`#3065`_)
|
||||
- Split ``{Command, Prefix}Handler`` And Make Attributes Immutable (`#3045`_)
|
||||
- Apply ``isort`` and Update ``pre-commit.ci`` Configuration (`#3049`_)
|
||||
- Adjust ``pre-commit`` Settings for ``isort`` (`#3043`_)
|
||||
- Add Version Check to Examples (`#3036`_)
|
||||
- Use ``Collection`` Instead of ``List`` and ``Tuple`` (`#3025`_)
|
||||
- Remove Client-Side Parameter Validation (`#3024`_)
|
||||
- Don't Pass Default Values of Optional Parameters to Telegram (`#2978`_)
|
||||
- Stabilize ``Application.run_*`` on Python 3.7 (`#3009`_)
|
||||
- Ignore Code Style Commits in ``git blame`` (`#3003`_)
|
||||
- Adjust Tests to Changed API Behavior (`#3002`_)
|
||||
|
||||
.. _`#2978`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2978
|
||||
.. _`#2998`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2998
|
||||
.. _`#2999`: https://github.com/python-telegram-bot/python-telegram-bot/pull/2999
|
||||
.. _`#3002`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3002
|
||||
.. _`#3003`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3003
|
||||
.. _`#3007`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3007
|
||||
.. _`#3009`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3009
|
||||
.. _`#3010`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3010
|
||||
.. _`#3012`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3012
|
||||
.. _`#3017`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3017
|
||||
.. _`#3019`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3019
|
||||
.. _`#3023`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3023
|
||||
.. _`#3024`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3024
|
||||
.. _`#3025`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3025
|
||||
.. _`#3026`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3026
|
||||
.. _`#3028`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3028
|
||||
.. _`#3030`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3030
|
||||
.. _`#3032`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3032
|
||||
.. _`#3033`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3033
|
||||
.. _`#3035`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3035
|
||||
.. _`#3036`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3036
|
||||
.. _`#3037`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3037
|
||||
.. _`#3043`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3043
|
||||
.. _`#3045`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3045
|
||||
.. _`#3046`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3046
|
||||
.. _`#3049`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3049
|
||||
.. _`#3052`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3052
|
||||
.. _`#3053`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3053
|
||||
.. _`#3055`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3055
|
||||
.. _`#3056`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3056
|
||||
.. _`#3057`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3057
|
||||
.. _`#3058`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3058
|
||||
.. _`#3059`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3059
|
||||
.. _`#3065`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3065
|
||||
.. _`#3067`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3067
|
||||
.. _`#3068`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3068
|
||||
.. _`#3069`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3069
|
||||
.. _`#3070`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3070
|
||||
.. _`#3072`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3072
|
||||
.. _`#3077`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3077
|
||||
.. _`#3078`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3078
|
||||
.. _`#3080`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3080
|
||||
.. _`#3081`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3081
|
||||
.. _`#3082`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3082
|
||||
.. _`#3089`: https://github.com/python-telegram-bot/python-telegram-bot/pull/3089
|
||||
|
||||
Version 20.0a0
|
||||
==============
|
||||
*Released 2022-05-06*
|
||||
@@ -72,9 +216,9 @@ New Features:
|
||||
by `DonalDuck004 <https://github.com/DonalDuck004>`__)
|
||||
- Add Method ``drop_chat/user_data`` to ``Dispatcher`` and Persistence
|
||||
(`#2852 <https://github.com/python-telegram-bot/python-telegram-bot/pull/2852>`__)
|
||||
- Add methods ``ChatPermissions.{all, no}_permissions`` ([#2948]
|
||||
- Add methods ``ChatPermissions.{all, no}_permissions`` (`#2948 <https://github.com/python-telegram-bot/python-telegram-bot/pull/2948>`__)
|
||||
- Full Support for API 6.0
|
||||
(`#2956 <https://github.com/python-telegram-bot/python-telegram-bot/pull/2956>`__)(https://github.com/python-telegram-bot/python-telegram-bot/pull/2948))
|
||||
(`#2956 <https://github.com/python-telegram-bot/python-telegram-bot/pull/2956>`__)
|
||||
- Add Python 3.10 to Test Suite
|
||||
(`#2968 <https://github.com/python-telegram-bot/python-telegram-bot/pull/2968>`__)
|
||||
|
||||
@@ -1520,7 +1664,7 @@ Changes
|
||||
- Lots of small improvements to our tests and documentation.
|
||||
|
||||
|
||||
.. _`see docs`: http://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.dispatcher.html#telegram.ext.Dispatcher.add_handler
|
||||
.. _`see docs`: https://docs.python-telegram-bot.org/en/stable/telegram.ext.dispatcher.html#telegram.ext.Dispatcher.add_handler
|
||||
.. _`#777`: https://github.com/python-telegram-bot/python-telegram-bot/pull/777
|
||||
.. _`#806`: https://github.com/python-telegram-bot/python-telegram-bot/pull/806
|
||||
.. _`#766`: https://github.com/python-telegram-bot/python-telegram-bot/pull/766
|
||||
@@ -1762,7 +1906,7 @@ Pre-version 7.0
|
||||
|
||||
- Implement Bot API 2.0
|
||||
- Almost complete recode of ``Dispatcher``
|
||||
- Please read the `Transistion Guide to 4.0 <https://github.com/python-telegram-bot/python-telegram-bot/wiki/Transistion-guide-to-Version-4.0>`_
|
||||
- Please read the `Transistion Guide to 4.0 <https://github.com/python-telegram-bot/python-telegram-bot/wiki/Transition-guide-to-Version-4.0>`_
|
||||
|
||||
**2016-03-22**
|
||||
|
||||
|
||||
+1
-1
@@ -49,4 +49,4 @@ Project maintainers who do not follow or enforce the Code of Conduct in good fai
|
||||
Attribution
|
||||
===========
|
||||
|
||||
This Code of Conduct is adapted from the `Contributor Covenant <http://contributor-covenant.org>`_, version 1.4, available at `http://contributor-covenant.org/version/1/4 <http://contributor-covenant.org/version/1/4/>`_.
|
||||
This Code of Conduct is adapted from the `Contributor Covenant <https://www.contributor-covenant.org>`_, version 1.4, available at `https://www.contributor-covenant.org/version/1/4 <https://www.contributor-covenant.org/version/1/4/>`_.
|
||||
|
||||
+14
-15
@@ -1,7 +1,7 @@
|
||||
..
|
||||
Make sure to apply any changes to this file to README_RAW.rst as well!
|
||||
|
||||
.. image:: https://github.com/python-telegram-bot/logos/blob/master/logo-text/png/ptb-logo-text_768.png?raw=true
|
||||
.. image:: https://raw.githubusercontent.com/python-telegram-bot/logos/master/logo-text/png/ptb-logo-text_768.png
|
||||
:align: center
|
||||
:target: https://python-telegram-bot.org
|
||||
:alt: python-telegram-bot Logo
|
||||
@@ -14,7 +14,7 @@
|
||||
:target: https://pypi.org/project/python-telegram-bot/
|
||||
:alt: Supported Python versions
|
||||
|
||||
.. image:: https://img.shields.io/badge/Bot%20API-6.0-blue?logo=telegram
|
||||
.. image:: https://img.shields.io/badge/Bot%20API-6.1-blue?logo=telegram
|
||||
:target: https://core.telegram.org/bots/api-changelog
|
||||
:alt: Supported Bot API versions
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
:alt: PyPi Package Monthly Download
|
||||
|
||||
.. image:: https://readthedocs.org/projects/python-telegram-bot/badge/?version=stable
|
||||
:target: https://python-telegram-bot.readthedocs.io/en/stable/
|
||||
:target: https://docs.python-telegram-bot.org/en/stable/
|
||||
:alt: Documentation Status
|
||||
|
||||
.. image:: https://img.shields.io/pypi/l/python-telegram-bot.svg
|
||||
@@ -35,15 +35,15 @@
|
||||
:alt: Github Actions workflow
|
||||
|
||||
.. image:: https://codecov.io/gh/python-telegram-bot/python-telegram-bot/branch/master/graph/badge.svg
|
||||
:target: https://codecov.io/gh/python-telegram-bot/python-telegram-bot
|
||||
:target: https://app.codecov.io/gh/python-telegram-bot/python-telegram-bot
|
||||
:alt: Code coverage
|
||||
|
||||
.. image:: http://isitmaintained.com/badge/resolution/python-telegram-bot/python-telegram-bot.svg
|
||||
:target: http://isitmaintained.com/project/python-telegram-bot/python-telegram-bot
|
||||
.. image:: https://isitmaintained.com/badge/resolution/python-telegram-bot/python-telegram-bot.svg
|
||||
:target: https://isitmaintained.com/project/python-telegram-bot/python-telegram-bot
|
||||
:alt: Median time to resolve an issue
|
||||
|
||||
.. image:: https://api.codacy.com/project/badge/Grade/99d901eaa09b44b4819aec05c330c968
|
||||
:target: https://www.codacy.com/app/python-telegram-bot/python-telegram-bot?utm_source=github.com&utm_medium=referral&utm_content=python-telegram-bot/python-telegram-bot&utm_campaign=Badge_Grade
|
||||
:target: https://app.codacy.com/gh/python-telegram-bot/python-telegram-bot/dashboard
|
||||
:alt: Code quality: Codacy
|
||||
|
||||
.. image:: https://deepsource.io/gh/python-telegram-bot/python-telegram-bot.svg/?label=active+issues
|
||||
@@ -93,7 +93,7 @@ Installing both ``python-telegram-bot`` and ``python-telegram-bot-raw`` in conju
|
||||
Telegram API support
|
||||
====================
|
||||
|
||||
All types and methods of the Telegram Bot API **6.0** are supported.
|
||||
All types and methods of the Telegram Bot API **6.1** are supported.
|
||||
|
||||
Installing
|
||||
==========
|
||||
@@ -121,9 +121,9 @@ Dependencies & Their Versions
|
||||
However, for some features using a 3rd party library is more sane than implementing the functionality again.
|
||||
The dependencies are:
|
||||
|
||||
* `httpx ~= 0.22.0 <https://www.python-httpx.org>`_ for ``telegram.request.HTTPXRequest``, the default networking backend
|
||||
* `httpx ~= 0.23.0 <https://www.python-httpx.org>`_ for ``telegram.request.HTTPXRequest``, the default networking backend
|
||||
* `tornado~=6.1 <https://www.tornadoweb.org/en/stable/>`_ for ``telegram.ext.Updater.start_webhook``
|
||||
* `cachetools~=5.0.0 <https://cachetools.readthedocs.io/en/latest/>`_ for ``telegram.ext.CallbackDataCache``
|
||||
* `cachetools~=5.2.0 <https://cachetools.readthedocs.io/en/latest/>`_ for ``telegram.ext.CallbackDataCache``
|
||||
* `APScheduler~=3.9.1 <https://apscheduler.readthedocs.io/en/3.x/>`_ for ``telegram.ext.JobQueue``
|
||||
|
||||
``python-telegram-bot`` is most useful when used along with additional libraries.
|
||||
@@ -136,8 +136,7 @@ Optional Dependencies
|
||||
|
||||
PTB can be installed with optional dependencies:
|
||||
|
||||
* ``pip install python-telegram-bot[passport]`` installs the `cryptography>=3.0 <https://cryptography.io>`_ library. Use this, if you want to use Telegram Passport related functionality.
|
||||
* ``pip install python-telegram-bot[json]`` installs the `ujson>=4.0.0 <https://pypi.org/project/ujson/>`_ library. It will then be used for JSON de- & encoding, which can bring speed up compared to the standard `json <https://docs.python.org/3/library/json.html>`_ library.
|
||||
* ``pip install python-telegram-bot[passport]`` installs the `cryptography>=3.0 <https://cryptography.io/en/stable>`_ library. Use this, if you want to use Telegram Passport related functionality.
|
||||
* ``pip install python-telegram-bot[socks]`` installs ``httpx[socks]``. Use this, if you want to work behind a Socks5 server.
|
||||
|
||||
Quick Start
|
||||
@@ -149,10 +148,10 @@ Moreover, the `Tutorial: Your first Bot <https://github.com/python-telegram-bot/
|
||||
Resources
|
||||
=========
|
||||
|
||||
- The `package documentation <https://python-telegram-bot.readthedocs.io/>`_ is the technical reference for ``python-telegram-bot``.
|
||||
It contains descriptions of all available classes, modules, methods and arguments.
|
||||
- The `package documentation <https://docs.python-telegram-bot.org/>`_ is the technical reference for ``python-telegram-bot``.
|
||||
It contains descriptions of all available classes, modules, methods and arguments as well as the `changelog <https://docs.python-telegram-bot.org/changelog.html>`_.
|
||||
- The `wiki <https://github.com/python-telegram-bot/python-telegram-bot/wiki/>`_ is home to number of more elaborate introductions of the different features of ``python-telegram-bot`` and other useful resources that go beyond the technical documentation.
|
||||
- Our `examples directory <https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/README.md>`_ contains several examples that showcase the different features of both the Bot API and ``python-telegram-bot``.
|
||||
- Our `examples section <https://docs.python-telegram-bot.org/examples.html>`_ contains several examples that showcase the different features of both the Bot API and ``python-telegram-bot``.
|
||||
Even if it is not your approach for learning, please take a look at ``echobot.py``. It is the de facto base for most of the bots out there.
|
||||
The code for these examples is released to the public domain, so you can start by grabbing the code and building on top of it.
|
||||
- The `official Telegram Bot API documentation <https://core.telegram.org/bots/api>`_ is of course always worth a read.
|
||||
|
||||
+13
-14
@@ -14,7 +14,7 @@
|
||||
:target: https://pypi.org/project/python-telegram-bot-raw/
|
||||
:alt: Supported Python versions
|
||||
|
||||
.. image:: https://img.shields.io/badge/Bot%20API-6.0-blue?logo=telegram
|
||||
.. image:: https://img.shields.io/badge/Bot%20API-6.1-blue?logo=telegram
|
||||
:target: https://core.telegram.org/bots/api-changelog
|
||||
:alt: Supported Bot API versions
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
:alt: PyPi Package Monthly Download
|
||||
|
||||
.. image:: https://readthedocs.org/projects/python-telegram-bot/badge/?version=stable
|
||||
:target: https://python-telegram-bot.readthedocs.io/
|
||||
:target: https://docs.python-telegram-bot.org/
|
||||
:alt: Documentation Status
|
||||
|
||||
.. image:: https://img.shields.io/pypi/l/python-telegram-bot-raw.svg
|
||||
@@ -34,16 +34,16 @@
|
||||
:target: https://github.com/python-telegram-bot/python-telegram-bot/
|
||||
:alt: Github Actions workflow
|
||||
|
||||
.. image:: https://codecov.io/gh/python-telegram-bot/python-telegram-bot/branch/master/graph/badge.svg
|
||||
:target: https://codecov.io/gh/python-telegram-bot/python-telegram-bot
|
||||
.. image:: https://app.codecov.io/gh/python-telegram-bot/python-telegram-bot
|
||||
:target: https://app.codecov.io/gh/python-telegram-bot/python-telegram-bot
|
||||
:alt: Code coverage
|
||||
|
||||
.. image:: http://isitmaintained.com/badge/resolution/python-telegram-bot/python-telegram-bot.svg
|
||||
:target: http://isitmaintained.com/project/python-telegram-bot/python-telegram-bot
|
||||
.. image:: https://isitmaintained.com/badge/resolution/python-telegram-bot/python-telegram-bot.svg
|
||||
:target: https://isitmaintained.com/project/python-telegram-bot/python-telegram-bot
|
||||
:alt: Median time to resolve an issue
|
||||
|
||||
.. image:: https://api.codacy.com/project/badge/Grade/99d901eaa09b44b4819aec05c330c968
|
||||
:target: https://www.codacy.com/app/python-telegram-bot/python-telegram-bot?utm_source=github.com&utm_medium=referral&utm_content=python-telegram-bot/python-telegram-bot&utm_campaign=Badge_Grade
|
||||
:target: https://app.codacy.com/gh/python-telegram-bot/python-telegram-bot/dashboard
|
||||
:alt: Code quality: Codacy
|
||||
|
||||
.. image:: https://deepsource.io/gh/python-telegram-bot/python-telegram-bot.svg/?label=active+issues
|
||||
@@ -89,7 +89,7 @@ Installing both ``python-telegram-bot`` and ``python-telegram-bot-raw`` in conju
|
||||
Telegram API support
|
||||
====================
|
||||
|
||||
All types and methods of the Telegram Bot API **6.0** are supported.
|
||||
All types and methods of the Telegram Bot API **6.1** are supported.
|
||||
|
||||
Installing
|
||||
==========
|
||||
@@ -122,7 +122,7 @@ Dependencies & Their Versions
|
||||
However, for some features using a 3rd party library is more sane than implementing the functionality again.
|
||||
The dependencies are:
|
||||
|
||||
* `httpx ~= 0.22.0 <https://www.python-httpx.org>`_ for ``telegram.request.HTTPXRequest``, the default networking backend
|
||||
* `httpx ~= 0.23.0 <https://www.python-httpx.org>`_ for ``telegram.request.HTTPXRequest``, the default networking backend
|
||||
|
||||
``python-telegram-bot`` is most useful when used along with additional libraries.
|
||||
To minimize dependency conflicts, we try to be liberal in terms of version requirements on the dependencies.
|
||||
@@ -134,8 +134,7 @@ Optional Dependencies
|
||||
|
||||
``python-telegram-bot-raw`` can be installed with optional dependencies:
|
||||
|
||||
* ``pip install python-telegram-bot[passport]`` installs the `cryptography <https://cryptography.io>`_ library. Use this, if you want to use Telegram Passport related functionality.
|
||||
* ``pip install python-telegram-bot[json]`` installs the `ujson <https://pypi.org/project/ujson/>`_ library. It will then be used for JSON de- & encoding, which can bring speed up compared to the standard `json <https://docs.python.org/3/library/json.html>`_ library.
|
||||
* ``pip install python-telegram-bot[passport]`` installs the `cryptography <https://cryptography.io/en/stable>`_ library. Use this, if you want to use Telegram Passport related functionality.
|
||||
* ``pip install python-telegram-bot[socks]`` installs the `PySocks <https://pypi.org/project/PySocks/>`_ library. Use this, if you want to work behind a Socks5 server.
|
||||
|
||||
Quick Start
|
||||
@@ -146,10 +145,10 @@ Our Wiki contains an `Introduction to the API <https://github.com/python-telegra
|
||||
Resources
|
||||
=========
|
||||
|
||||
- The `package documentation <https://python-telegram-bot.readthedocs.io/>`_ is the technical reference for ``python-telegram-bot``.
|
||||
It contains descriptions of all available classes, modules, methods and arguments.
|
||||
- The `package documentation <https://docs.python-telegram-bot.org/>`_ is the technical reference for ``python-telegram-bot``.
|
||||
It contains descriptions of all available classes, modules, methods and arguments as well as the `changelog <https://docs.python-telegram-bot.org/changelog.html>`_.
|
||||
- The `wiki <https://github.com/python-telegram-bot/python-telegram-bot/wiki/>`_ is home to number of more elaborate introductions of the different features of ``python-telegram-bot`` and other useful resources that go beyond the technical documentation.
|
||||
- Our `examples directory <https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/README.md>`_ contains several examples that showcase the different features of both the Bot API and ``python-telegram-bot``.
|
||||
- Our `examples section <https://docs.python-telegram-bot.org/examples.html>`_ contains several examples that showcase the different features of both the Bot API and ``python-telegram-bot``.
|
||||
Even if it is not your approach for learning, please take a look at ``echobot.py``. It is the de facto base for most of the bots out there.
|
||||
The code for these examples is released to the public domain, so you can start by grabbing the code and building on top of it.
|
||||
- The `official Telegram Bot API documentation <https://core.telegram.org/bots/api>`_ is of course always worth a read.
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
sphinx==4.5.0
|
||||
sphinx==5.0.2
|
||||
sphinx-pypi-upload
|
||||
furo==2022.04.07
|
||||
# Can be replaced with a sphinx-paramlinks==... dependency once a version is released that
|
||||
# includes the commit mentioned below and maybe even
|
||||
# https://github.com/sqlalchemyorg/sphinx-paramlinks/pull/14
|
||||
git+https://github.com/sqlalchemyorg/sphinx-paramlinks.git@acedb03149e3f87ff599174b033754c2f58f1c95
|
||||
furo==2022.6.21
|
||||
sphinx-paramlinks==0.5.4
|
||||
sphinxcontrib-mermaid==0.7.1
|
||||
@@ -0,0 +1,3 @@
|
||||
.mermaid svg {
|
||||
height: auto;
|
||||
}
|
||||
@@ -263,6 +263,8 @@
|
||||
:align: left
|
||||
:widths: 1 4
|
||||
|
||||
* - :meth:`~telegram.Bot.create_invoice_link`
|
||||
- Used to generate an HTTP link for an invoice
|
||||
* - :meth:`~telegram.Bot.close`
|
||||
- Used for closing server instance when switching to another local server
|
||||
* - :meth:`~telegram.Bot.log_out`
|
||||
|
||||
+65
-185
@@ -1,16 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Python Telegram Bot documentation build configuration file, created by
|
||||
# sphinx-quickstart on Mon Aug 10 22:25:07 2015.
|
||||
#
|
||||
# This file is execfile()d with the current directory set to its
|
||||
# containing dir.
|
||||
#
|
||||
# Note that not all possible configuration values are present in this
|
||||
# autogenerated file.
|
||||
#
|
||||
# All configuration values have a default; values that are commented out
|
||||
# serve to show the default.
|
||||
import inspect
|
||||
import os
|
||||
import re
|
||||
@@ -32,6 +19,19 @@ from sphinx.util import logging
|
||||
sys.path.insert(0, os.path.abspath("../.."))
|
||||
|
||||
# -- General configuration ------------------------------------------------
|
||||
# General information about the project.
|
||||
project = "python-telegram-bot"
|
||||
copyright = "2015-2022, Leandro Toledo"
|
||||
author = "Leandro Toledo"
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = "20.0a2" # telegram.__version__[:3]
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = "20.0a2" # telegram.__version__
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
needs_sphinx = "4.5.0"
|
||||
@@ -45,6 +45,7 @@ extensions = [
|
||||
"sphinx.ext.intersphinx",
|
||||
"sphinx.ext.linkcode",
|
||||
"sphinx_paramlinks",
|
||||
"sphinxcontrib.mermaid",
|
||||
]
|
||||
|
||||
# Use intersphinx to reference the python builtin library docs
|
||||
@@ -53,76 +54,49 @@ intersphinx_mapping = {
|
||||
"APScheduler": ("https://apscheduler.readthedocs.io/en/3.x/", None),
|
||||
}
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ["_templates"]
|
||||
|
||||
# The suffix(es) of source filenames.
|
||||
# You can specify multiple suffix as a list of string:
|
||||
source_suffix = ".rst"
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = "index"
|
||||
|
||||
# -- Extension settings ------------------------------------------------
|
||||
napoleon_use_admonition_for_examples = True
|
||||
|
||||
# Don't show type hints in the signature - that just makes it hardly readable
|
||||
# and we document the types anyway
|
||||
autodoc_typehints = "none"
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ["_templates"]
|
||||
|
||||
# Fail on warnings & unresolved references etc
|
||||
nitpicky = True
|
||||
|
||||
# Paramlink style
|
||||
paramlinks_hyperlink_param = "name"
|
||||
|
||||
# Linkcheck settings
|
||||
linkcheck_ignore = [
|
||||
# Let's not check issue/PR links - that's wasted resources
|
||||
r"http(s)://github\.com/python-telegram-bot/python-telegram-bot/(issues|pull)/\d+/?",
|
||||
# For some reason linkcheck has a problem with these two:
|
||||
re.escape("https://github.com/python-telegram-bot/python-telegram-bot/discussions/new"),
|
||||
re.escape("https://github.com/python-telegram-bot/python-telegram-bot/issues/new"),
|
||||
# Anchors are apparently inserted by GitHub dynamically, so let's skip checking them
|
||||
"https://github.com/python-telegram-bot/python-telegram-bot/tree/master/examples#",
|
||||
r"https://github\.com/python-telegram-bot/python-telegram-bot/wiki/[\w\-_,]+\#",
|
||||
]
|
||||
linkcheck_allowed_redirects = {
|
||||
# Redirects to the default version are okay
|
||||
r"https://docs\.python-telegram-bot\.org/.*": r"https://docs\.python-telegram-bot\.org/en/[\w\d\.]+/.*",
|
||||
# pre-commit.ci always redirects to the latest run
|
||||
re.escape(
|
||||
"https://results.pre-commit.ci/latest/github/python-telegram-bot/python-telegram-bot/master"
|
||||
): r"https://results\.pre-commit\.ci/run/github/.*",
|
||||
}
|
||||
|
||||
# The suffix(es) of source filenames.
|
||||
# You can specify multiple suffix as a list of string:
|
||||
# source_suffix = ['.rst', '.md']
|
||||
source_suffix = ".rst"
|
||||
|
||||
# The encoding of source files.
|
||||
# source_encoding = 'utf-8-sig'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = "index"
|
||||
|
||||
# General information about the project.
|
||||
project = "python-telegram-bot"
|
||||
copyright = "2015-2021, Leandro Toledo"
|
||||
author = "Leandro Toledo"
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = "20.0a0" # telegram.__version__[:3]
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = "20.0a0" # telegram.__version__
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
#
|
||||
# This is also used if you do content translation via gettext catalogs.
|
||||
# Usually you set "language" from the command line for these cases.
|
||||
language = None
|
||||
|
||||
# There are two options for replacing |today|: either, you set today to some
|
||||
# non-false value, then it is used:
|
||||
# today = ''
|
||||
# Else, today_fmt is used as the format for a strftime call.
|
||||
# today_fmt = '%B %d, %Y'
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
exclude_patterns = []
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all
|
||||
# documents.
|
||||
# default_role = None
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
# add_function_parentheses = True
|
||||
|
||||
# If true, the current module name will be prepended to all description
|
||||
# unit titles (such as .. function::).
|
||||
# add_module_names = True
|
||||
|
||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
||||
# output. They are ignored by default.
|
||||
# show_authors = False
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = "sphinx"
|
||||
@@ -130,16 +104,9 @@ pygments_style = "sphinx"
|
||||
# Decides the language used for syntax highlighting of code blocks.
|
||||
highlight_language = "python3"
|
||||
|
||||
# A list of ignored prefixes for module index sorting.
|
||||
# modindex_common_prefix = []
|
||||
|
||||
# If true, keep warnings as "system message" paragraphs in the built documents.
|
||||
# keep_warnings = False
|
||||
|
||||
# If true, `todo` and `todoList` produce output, else they produce nothing.
|
||||
todo_include_todos = False
|
||||
|
||||
|
||||
# -- Options for HTML output ----------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
@@ -228,16 +195,10 @@ html_theme_options = {
|
||||
],
|
||||
}
|
||||
|
||||
# Add any paths that contain custom themes here, relative to this directory.
|
||||
# html_theme_path = []
|
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to
|
||||
# "<project> v<release> documentation".
|
||||
html_title = f"python-telegram-bot<br> v{version}"
|
||||
|
||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||
# html_short_title = None
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top
|
||||
# of the sidebar.
|
||||
html_logo = "ptb-logo_1024.png"
|
||||
@@ -251,72 +212,19 @@ html_favicon = "ptb-logo_1024.ico"
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ["_static"]
|
||||
|
||||
html_css_files = ["style_external_link.css"]
|
||||
|
||||
# Add any extra paths that contain custom files (such as robots.txt or
|
||||
# .htaccess) here, relative to this directory. These files are copied
|
||||
# directly to the root of the documentation.
|
||||
# html_extra_path = []
|
||||
|
||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||
# using the given strftime format.
|
||||
# html_last_updated_fmt = '%b %d, %Y'
|
||||
|
||||
# If true, SmartyPants will be used to convert quotes and dashes to
|
||||
# typographically correct entities.
|
||||
# html_use_smartypants = True
|
||||
|
||||
# Custom sidebar templates, maps document names to template names.
|
||||
# html_sidebars = {}
|
||||
|
||||
# Additional templates that should be rendered to pages, maps page names to
|
||||
# template names.
|
||||
# html_additional_pages = {}
|
||||
|
||||
# If false, no module index is generated.
|
||||
# html_domain_indices = True
|
||||
|
||||
# If false, no index is generated.
|
||||
# html_use_index = True
|
||||
|
||||
# If true, the index is split into individual pages for each letter.
|
||||
# html_split_index = False
|
||||
|
||||
# If true, links to the reST sources are added to the pages.
|
||||
# html_show_sourcelink = True
|
||||
|
||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
||||
# html_show_sphinx = True
|
||||
|
||||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
||||
# html_show_copyright = True
|
||||
|
||||
# If true, an OpenSearch description file will be output, and all pages will
|
||||
# contain a <link> tag referring to it. The value of this option must be the
|
||||
# base URL from which the finished HTML is served.
|
||||
# html_use_opensearch = ''
|
||||
|
||||
# This is the file name suffix for HTML files (e.g. ".xhtml").
|
||||
# html_file_suffix = None
|
||||
|
||||
# Language to be used for generating the HTML full-text search index.
|
||||
# Sphinx supports the following languages:
|
||||
# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'
|
||||
# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr'
|
||||
# html_search_language = 'en'
|
||||
|
||||
# A dictionary with options for the search language support, empty by default.
|
||||
# Now only 'ja' uses this config value
|
||||
# html_search_options = {'type': 'default'}
|
||||
|
||||
# The name of a javascript file (relative to the configuration directory) that
|
||||
# implements a search results scorer. If empty, the default will be used.
|
||||
# html_search_scorer = 'scorer.js'
|
||||
html_css_files = [
|
||||
"style_external_link.css",
|
||||
"style_mermaid_diagrams.css",
|
||||
]
|
||||
html_permalinks_icon = "¶" # Furo's default permalink icon is `#`` which doesn't look great imo.
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = "python-telegram-bot-doc"
|
||||
|
||||
# The base URL which points to the root of the HTML documentation. It is used to indicate the
|
||||
# location of document using The Canonical Link Relation. Default: ''.
|
||||
html_baseurl = "https://docs.python-telegram-bot.org"
|
||||
|
||||
# -- Options for LaTeX output ---------------------------------------------
|
||||
|
||||
latex_elements = {
|
||||
@@ -343,32 +251,12 @@ latex_documents = [
|
||||
# the title page.
|
||||
latex_logo = "ptb-logo_1024.png"
|
||||
|
||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
||||
# not chapters.
|
||||
# latex_use_parts = False
|
||||
|
||||
# If true, show page references after internal links.
|
||||
# latex_show_pagerefs = False
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
# latex_show_urls = False
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
# latex_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
# latex_domain_indices = True
|
||||
|
||||
|
||||
# -- Options for manual page output ---------------------------------------
|
||||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [(master_doc, "python-telegram-bot", "python-telegram-bot Documentation", [author], 1)]
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
# man_show_urls = False
|
||||
|
||||
|
||||
# -- Options for Texinfo output -------------------------------------------
|
||||
|
||||
@@ -387,22 +275,6 @@ texinfo_documents = [
|
||||
),
|
||||
]
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
# texinfo_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
# texinfo_domain_indices = True
|
||||
|
||||
# How to display URL addresses: 'footnote', 'no', or 'inline'.
|
||||
# texinfo_show_urls = 'footnote'
|
||||
|
||||
# If true, do not generate a @detailmenu in the "Top" node's menu.
|
||||
# texinfo_no_detailmenu = False
|
||||
|
||||
# Napoleon stuff
|
||||
|
||||
napoleon_use_admonition_for_examples = True
|
||||
|
||||
# -- script stuff --------------------------------------------------------
|
||||
|
||||
# get the sphinx(!) logger
|
||||
@@ -444,9 +316,17 @@ class TGConstXRefRole(PyXRefRole):
|
||||
if isinstance(value, telegram.constants.FileSizeLimit):
|
||||
return f"{int(value.value / 1e6)} MB", target
|
||||
return repr(value.value), target
|
||||
# Just for Bot API version number auto add in constants:
|
||||
if isinstance(value, str) and target == "telegram.constants.BOT_API_VERSION":
|
||||
# Just for (Bot API) versions number auto add in constants:
|
||||
if isinstance(value, str) and target in (
|
||||
"telegram.constants.BOT_API_VERSION",
|
||||
"telegram.__version__",
|
||||
):
|
||||
return value, target
|
||||
if isinstance(value, tuple) and target in (
|
||||
"telegram.constants.BOT_API_VERSION_INFO",
|
||||
"telegram.__version_info__",
|
||||
):
|
||||
return repr(value), target
|
||||
sphinx_logger.warning(
|
||||
f"%s:%d: WARNING: Did not convert reference %s. :{CONSTANTS_ROLE}: is not supposed"
|
||||
" to be used with this type of target.",
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
``arbitrarycallbackdatabot.py``
|
||||
===============================
|
||||
|
||||
.. literalinclude:: ../../examples/arbitrarycallbackdatabot.py
|
||||
:language: python
|
||||
:linenos:
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
``chatmemberbot.py``
|
||||
====================
|
||||
|
||||
.. literalinclude:: ../../examples/chatmemberbot.py
|
||||
:language: python
|
||||
:linenos:
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
``contexttypesbot.py``
|
||||
======================
|
||||
|
||||
.. literalinclude:: ../../examples/contexttypesbot.py
|
||||
:language: python
|
||||
:linenos:
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
``conversationbot.py``
|
||||
======================
|
||||
|
||||
.. literalinclude:: ../../examples/conversationbot.py
|
||||
:language: python
|
||||
:linenos:
|
||||
|
||||
.. _conversationbot-diagram:
|
||||
|
||||
State Diagram
|
||||
-------------
|
||||
|
||||
.. mermaid:: ../../examples/conversationbot.mmd
|
||||
@@ -0,0 +1,13 @@
|
||||
``conversationbot2.py``
|
||||
=======================
|
||||
|
||||
.. literalinclude:: ../../examples/conversationbot2.py
|
||||
:language: python
|
||||
:linenos:
|
||||
|
||||
.. _conversationbot2-diagram:
|
||||
|
||||
State Diagram
|
||||
-------------
|
||||
|
||||
.. mermaid:: ../../examples/conversationbot2.mmd
|
||||
@@ -0,0 +1,7 @@
|
||||
``customwebhookbot.py``
|
||||
=======================
|
||||
|
||||
.. literalinclude:: ../../examples/customwebhookbot.py
|
||||
:language: python
|
||||
:linenos:
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
``deeplinking.py``
|
||||
==================
|
||||
|
||||
.. literalinclude:: ../../examples/deeplinking.py
|
||||
:language: python
|
||||
:linenos:
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
``echobot.py``
|
||||
==============
|
||||
|
||||
.. literalinclude:: ../../examples/echobot.py
|
||||
:language: python
|
||||
:linenos:
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
``errorhandlerbot.py``
|
||||
======================
|
||||
|
||||
.. literalinclude:: ../../examples/errorhandlerbot.py
|
||||
:language: python
|
||||
:linenos:
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
``inlinebot.py``
|
||||
================
|
||||
|
||||
.. literalinclude:: ../../examples/inlinebot.py
|
||||
:language: python
|
||||
:linenos:
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
``inlinekeyboard.py``
|
||||
=====================
|
||||
|
||||
.. literalinclude:: ../../examples/inlinekeyboard.py
|
||||
:language: python
|
||||
:linenos:
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
``inlinekeyboard2.py``
|
||||
======================
|
||||
|
||||
.. literalinclude:: ../../examples/inlinekeyboard2.py
|
||||
:language: python
|
||||
:linenos:
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
``nestedconversationbot.py``
|
||||
============================
|
||||
|
||||
.. literalinclude:: ../../examples/nestedconversationbot.py
|
||||
:language: python
|
||||
:linenos:
|
||||
|
||||
.. _nestedconversationbot-diagram:
|
||||
|
||||
State Diagram
|
||||
-------------
|
||||
|
||||
.. mermaid:: ../../examples/nestedconversationbot.mmd
|
||||
@@ -0,0 +1,16 @@
|
||||
``passportbot.py``
|
||||
==================
|
||||
|
||||
.. literalinclude:: ../../examples/passportbot.py
|
||||
:language: python
|
||||
:linenos:
|
||||
|
||||
.. _passportbot-html:
|
||||
|
||||
HTML Page
|
||||
---------
|
||||
|
||||
.. literalinclude:: ../../examples/passportbot.html
|
||||
:language: html
|
||||
:linenos:
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
``paymentbot.py``
|
||||
=================
|
||||
|
||||
.. literalinclude:: ../../examples/paymentbot.py
|
||||
:language: python
|
||||
:linenos:
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
``persistentconversationbot.py``
|
||||
================================
|
||||
|
||||
.. literalinclude:: ../../examples/persistentconversationbot.py
|
||||
:language: python
|
||||
:linenos:
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
``pollbot.py``
|
||||
==============
|
||||
|
||||
.. literalinclude:: ../../examples/pollbot.py
|
||||
:language: python
|
||||
:linenos:
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
`rawapibot.py`
|
||||
==============
|
||||
|
||||
This example uses only the pure, "bare-metal" API wrapper.
|
||||
|
||||
|
||||
|
||||
.. literalinclude:: ../../examples/rawapibot.py
|
||||
:language: python
|
||||
:linenos:
|
||||
|
||||
@@ -0,0 +1,194 @@
|
||||
Examples
|
||||
========
|
||||
|
||||
In this section we display small examples to show what a bot written with
|
||||
``python-telegram-bot`` looks like.
|
||||
Some bots focus on one specific
|
||||
aspect of the Telegram Bot API while others focus on one of the
|
||||
mechanics of this library. Except for the
|
||||
:any:`examples.rawapibot` example, they all use the high-level
|
||||
framework this library provides with the
|
||||
:any:`telegram.ext <telegram.ext>` submodule.
|
||||
|
||||
All examples are licensed under the `CC0
|
||||
License <https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/LICENSE.txt>`__
|
||||
and are therefore fully dedicated to the public domain. You can use them
|
||||
as the base for your own bots without worrying about copyrights.
|
||||
|
||||
Do note that we ignore one pythonic convention. Best practice would
|
||||
dictate, in many handler callbacks function signatures, to replace the
|
||||
argument ``context`` with an underscore, since ``context`` is an unused
|
||||
local variable in those callbacks. However, since these are examples and
|
||||
not having a name for that argument confuses beginners, we decided to
|
||||
have it present.
|
||||
|
||||
:any:`examples.echobot`
|
||||
-----------------------
|
||||
|
||||
This is probably the base for most of the bots made with
|
||||
``python-telegram-bot``. It simply replies to each text message with a
|
||||
message that contains the same text.
|
||||
|
||||
:any:`examples.timerbot`
|
||||
------------------------
|
||||
|
||||
This bot uses the
|
||||
:class:`telegram.ext.JobQueue`
|
||||
class to send timed messages. The user sets a timer by using ``/set``
|
||||
command with a specific time, for example ``/set 30``. The bot then sets
|
||||
up a job to send a message to that user after 30 seconds. The user can
|
||||
also cancel the timer by sending ``/unset``. To learn more about the
|
||||
``JobQueue``, read `this wiki
|
||||
article <https://github.com/python-telegram-bot/python-telegram-bot/wiki/Extensions-%E2%80%93-JobQueue>`__.
|
||||
|
||||
:any:`examples.conversationbot`
|
||||
-------------------------------
|
||||
|
||||
A common task for a bot is to ask information from the user. In v5.0 of
|
||||
this library, we introduced the
|
||||
:class:`telegram.ext.ConversationHandler`
|
||||
for that exact purpose. This example uses it to retrieve
|
||||
user-information in a conversation-like style. To get a better
|
||||
understanding, take a look at the :ref:`state diagrem <conversationbot-diagram>`.
|
||||
|
||||
:any:`examples.conversationbot2`
|
||||
--------------------------------
|
||||
|
||||
A more complex example of a bot that uses the ``ConversationHandler``.
|
||||
It is also more confusing. Good thing there is a :ref:`fancy state diagram <conversationbot2-diagram>`.
|
||||
for this one, too!
|
||||
|
||||
:any:`examples.nestedconversationbot`
|
||||
-------------------------------------
|
||||
|
||||
A even more complex example of a bot that uses the nested
|
||||
``ConversationHandler``\ s. While it’s certainly not that complex that
|
||||
you couldn’t built it without nested ``ConversationHanldler``\ s, it
|
||||
gives a good impression on how to work with them. Of course, there is a
|
||||
:ref:`fancy state diagram <nestedconversationbot-diagram>`
|
||||
for this example, too!
|
||||
|
||||
:any:`examples.persistentconversationbot`
|
||||
-----------------------------------------
|
||||
|
||||
A basic example of a bot store conversation state and user_data over
|
||||
multiple restarts.
|
||||
|
||||
:any:`examples.inlinekeyboard`
|
||||
------------------------------
|
||||
|
||||
This example sheds some light on inline keyboards, callback queries and
|
||||
message editing. A wiki site explaining this examples lives
|
||||
`here <https://github.com/python-telegram-bot/python-telegram-bot/wiki/InlineKeyboard-Example>`__.
|
||||
|
||||
:any:`examples.inlinekeyboard2`
|
||||
-------------------------------
|
||||
|
||||
A more complex example about inline keyboards, callback queries and
|
||||
message editing. This example showcases how an interactive menu could be
|
||||
build using inline keyboards.
|
||||
|
||||
:any:`examples.deeplinking`
|
||||
---------------------------
|
||||
|
||||
A basic example on how to use deeplinking with inline keyboards.
|
||||
|
||||
:any:`examples.inlinebot`
|
||||
-------------------------
|
||||
|
||||
A basic example of an `inline
|
||||
bot <https://core.telegram.org/bots/inline>`__. Don’t forget to enable
|
||||
inline mode with `@BotFather <https://telegram.me/BotFather>`_.
|
||||
|
||||
:any:`examples.pollbot`
|
||||
-----------------------
|
||||
|
||||
This example sheds some light on polls, poll answers and the
|
||||
corresponding handlers.
|
||||
|
||||
:any:`examples.passportbot`
|
||||
---------------------------
|
||||
|
||||
A basic example of a bot that can accept passports. Use in combination
|
||||
with the :ref:`HTML page <passportbot-html>`.
|
||||
Don’t forget to enable and configure payments with
|
||||
`@BotFather <https://telegram.me/BotFather>`_. Check out this
|
||||
`guide <https://github.com/python-telegram-bot/python-telegram-bot/wiki/Telegram-Passport>`__
|
||||
on Telegram passports in PTB.
|
||||
|
||||
:any:`examples.paymentbot`
|
||||
--------------------------
|
||||
|
||||
A basic example of a bot that can accept payments. Don’t forget to
|
||||
enable and configure payments with
|
||||
`@BotFather <https://telegram.me/BotFather>`_.
|
||||
|
||||
:any:`examples.errorhandlerbot`
|
||||
-------------------------------
|
||||
|
||||
A basic example on how to set up a custom error handler.
|
||||
|
||||
:any:`examples.chatmemberbot`
|
||||
-----------------------------
|
||||
|
||||
A basic example on how ``(my_)chat_member`` updates can be used.
|
||||
|
||||
:any:`examples.webappbot`
|
||||
-------------------------
|
||||
|
||||
A basic example of how `Telegram
|
||||
WebApps <https://core.telegram.org/bots/webapps>`__ can be used. Use in
|
||||
combination with the :ref:`HTML page <webappbot-html>`.
|
||||
For your convenience, this file is hosted by the PTB team such that you
|
||||
don’t need to host it yourself. Uses the
|
||||
`iro.js <https://iro.js.org>`__ JavaScript library to showcase a
|
||||
user interface that is hard to achieve with native Telegram
|
||||
functionality.
|
||||
|
||||
:any:`examples.contexttypesbot`
|
||||
-------------------------------
|
||||
|
||||
This example showcases how ``telegram.ext.ContextTypes`` can be used to
|
||||
customize the ``context`` argument of handler and job callbacks.
|
||||
|
||||
:any:`examples.customwebhookbot`
|
||||
--------------------------------
|
||||
|
||||
This example showcases how a custom webhook setup can be used in
|
||||
combination with ``telegram.ext.Application``.
|
||||
|
||||
:any:`examples.arbitrarycallbackdatabot`
|
||||
----------------------------------------
|
||||
|
||||
This example showcases how PTBs “arbitrary callback data” feature can be
|
||||
used.
|
||||
|
||||
Pure API
|
||||
--------
|
||||
|
||||
The :any:`examples.rawapibot` example example uses only the pure, “bare-metal” API wrapper.
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
|
||||
examples.arbitrarycallbackdatabot
|
||||
examples.chatmemberbot
|
||||
examples.contexttypesbot
|
||||
examples.conversationbot
|
||||
examples.conversationbot2
|
||||
examples.customwebhookbot
|
||||
examples.deeplinking
|
||||
examples.echobot
|
||||
examples.errorhandlerbot
|
||||
examples.inlinebot
|
||||
examples.inlinekeyboard
|
||||
examples.inlinekeyboard2
|
||||
examples.nestedconversationbot
|
||||
examples.passportbot
|
||||
examples.paymentbot
|
||||
examples.persistentconversationbot
|
||||
examples.pollbot
|
||||
examples.rawapibot
|
||||
examples.timerbot
|
||||
examples.webappbot
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
``timerbot.py``
|
||||
===============
|
||||
|
||||
.. literalinclude:: ../../examples/timerbot.py
|
||||
:language: python
|
||||
:linenos:
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
``webappbot.py``
|
||||
================
|
||||
|
||||
.. literalinclude:: ../../examples/webappbot.py
|
||||
:language: python
|
||||
:linenos:
|
||||
|
||||
.. _webappbot-html:
|
||||
|
||||
HTML Page
|
||||
---------
|
||||
|
||||
.. literalinclude:: ../../examples/webappbot.html
|
||||
:language: html
|
||||
:linenos:
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
.. include:: ../../README.rst
|
||||
|
||||
.. The toctrees are hidden such that they don't reander on the start page but still include the contents into the documentation.
|
||||
.. The toctrees are hidden such that they don't render on the start page but still include the contents into the documentation.
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
@@ -16,6 +16,13 @@
|
||||
telegram_auxil
|
||||
Telegrams Bot API Docs <https://core.telegram.org/bots/api>
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
:caption: Resources
|
||||
|
||||
examples
|
||||
Wiki <https://github.com/python-telegram-bot/python-telegram-bot/wiki>
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
:caption: Project
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
telegram.ext.BaseHandler
|
||||
========================
|
||||
|
||||
.. autoclass:: telegram.ext.BaseHandler
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -1,6 +0,0 @@
|
||||
telegram.ext.Handler
|
||||
====================
|
||||
|
||||
.. autoclass:: telegram.ext.Handler
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -3,32 +3,32 @@ telegram.ext package
|
||||
|
||||
.. toctree::
|
||||
|
||||
telegram.ext.extbot
|
||||
telegram.ext.applicationbuilder
|
||||
telegram.ext.application
|
||||
telegram.ext.applicationbuilder
|
||||
telegram.ext.applicationhandlerstop
|
||||
telegram.ext.updater
|
||||
telegram.ext.callbackcontext
|
||||
telegram.ext.job
|
||||
telegram.ext.jobqueue
|
||||
telegram.ext.contexttypes
|
||||
telegram.ext.defaults
|
||||
telegram.ext.extbot
|
||||
telegram.ext.job
|
||||
telegram.ext.jobqueue
|
||||
telegram.ext.updater
|
||||
|
||||
Handlers
|
||||
--------
|
||||
|
||||
.. toctree::
|
||||
|
||||
telegram.ext.handler
|
||||
telegram.ext.basehandler
|
||||
telegram.ext.callbackqueryhandler
|
||||
telegram.ext.chatjoinrequesthandler
|
||||
telegram.ext.chatmemberhandler
|
||||
telegram.ext.choseninlineresulthandler
|
||||
telegram.ext.commandhandler
|
||||
telegram.ext.conversationhandler
|
||||
telegram.ext.filters
|
||||
telegram.ext.inlinequeryhandler
|
||||
telegram.ext.messagehandler
|
||||
telegram.ext.filters
|
||||
telegram.ext.pollanswerhandler
|
||||
telegram.ext.pollhandler
|
||||
telegram.ext.precheckoutqueryhandler
|
||||
@@ -44,9 +44,9 @@ Persistence
|
||||
.. toctree::
|
||||
|
||||
telegram.ext.basepersistence
|
||||
telegram.ext.dictpersistence
|
||||
telegram.ext.persistenceinput
|
||||
telegram.ext.picklepersistence
|
||||
telegram.ext.dictpersistence
|
||||
|
||||
Arbitrary Callback Data
|
||||
-----------------------
|
||||
|
||||
+38
-29
@@ -1,6 +1,15 @@
|
||||
telegram package
|
||||
================
|
||||
|
||||
Version Constants
|
||||
-----------------
|
||||
|
||||
.. automodule:: telegram
|
||||
:members: __version__, __version_info__, __bot_api_version__, __bot_api_version_info__
|
||||
|
||||
Available Types
|
||||
---------------
|
||||
|
||||
.. toctree::
|
||||
|
||||
telegram.animation
|
||||
@@ -8,13 +17,13 @@ telegram package
|
||||
telegram.bot
|
||||
telegram.botcommand
|
||||
telegram.botcommandscope
|
||||
telegram.botcommandscopedefault
|
||||
telegram.botcommandscopeallprivatechats
|
||||
telegram.botcommandscopeallgroupchats
|
||||
telegram.botcommandscopeallchatadministrators
|
||||
telegram.botcommandscopeallgroupchats
|
||||
telegram.botcommandscopeallprivatechats
|
||||
telegram.botcommandscopechat
|
||||
telegram.botcommandscopechatadministrators
|
||||
telegram.botcommandscopechatmember
|
||||
telegram.botcommandscopedefault
|
||||
telegram.callbackquery
|
||||
telegram.chat
|
||||
telegram.chatadministratorrights
|
||||
@@ -22,12 +31,12 @@ telegram package
|
||||
telegram.chatjoinrequest
|
||||
telegram.chatlocation
|
||||
telegram.chatmember
|
||||
telegram.chatmemberowner
|
||||
telegram.chatmemberadministrator
|
||||
telegram.chatmembermember
|
||||
telegram.chatmemberrestricted
|
||||
telegram.chatmemberleft
|
||||
telegram.chatmemberbanned
|
||||
telegram.chatmemberleft
|
||||
telegram.chatmembermember
|
||||
telegram.chatmemberowner
|
||||
telegram.chatmemberrestricted
|
||||
telegram.chatmemberupdated
|
||||
telegram.chatpermissions
|
||||
telegram.chatphoto
|
||||
@@ -55,15 +64,15 @@ telegram package
|
||||
telegram.menubuttonwebapp
|
||||
telegram.message
|
||||
telegram.messageautodeletetimerchanged
|
||||
telegram.messageid
|
||||
telegram.messageentity
|
||||
telegram.messageid
|
||||
telegram.photosize
|
||||
telegram.poll
|
||||
telegram.pollanswer
|
||||
telegram.polloption
|
||||
telegram.proximityalerttriggered
|
||||
telegram.replykeyboardremove
|
||||
telegram.replykeyboardmarkup
|
||||
telegram.replykeyboardremove
|
||||
telegram.sentwebappmessage
|
||||
telegram.telegramobject
|
||||
telegram.update
|
||||
@@ -86,15 +95,16 @@ Stickers
|
||||
|
||||
.. toctree::
|
||||
|
||||
telegram.maskposition
|
||||
telegram.sticker
|
||||
telegram.stickerset
|
||||
telegram.maskposition
|
||||
|
||||
Inline Mode
|
||||
-----------
|
||||
|
||||
.. toctree::
|
||||
|
||||
telegram.choseninlineresult
|
||||
telegram.inlinequery
|
||||
telegram.inlinequeryresult
|
||||
telegram.inlinequeryresultarticle
|
||||
@@ -123,29 +133,28 @@ Inline Mode
|
||||
telegram.inputvenuemessagecontent
|
||||
telegram.inputcontactmessagecontent
|
||||
telegram.inputinvoicemessagecontent
|
||||
telegram.choseninlineresult
|
||||
|
||||
Payments
|
||||
--------
|
||||
|
||||
.. toctree::
|
||||
|
||||
telegram.labeledprice
|
||||
telegram.invoice
|
||||
telegram.shippingaddress
|
||||
telegram.labeledprice
|
||||
telegram.orderinfo
|
||||
telegram.shippingoption
|
||||
telegram.successfulpayment
|
||||
telegram.shippingquery
|
||||
telegram.precheckoutquery
|
||||
telegram.shippingaddress
|
||||
telegram.shippingoption
|
||||
telegram.shippingquery
|
||||
telegram.successfulpayment
|
||||
|
||||
Games
|
||||
-----
|
||||
|
||||
.. toctree::
|
||||
|
||||
telegram.game
|
||||
telegram.callbackgame
|
||||
telegram.game
|
||||
telegram.gamehighscore
|
||||
|
||||
Passport
|
||||
@@ -153,25 +162,25 @@ Passport
|
||||
|
||||
.. toctree::
|
||||
|
||||
telegram.credentials
|
||||
telegram.datacredentials
|
||||
telegram.encryptedcredentials
|
||||
telegram.encryptedpassportelement
|
||||
telegram.filecredentials
|
||||
telegram.iddocumentdata
|
||||
telegram.passportdata
|
||||
telegram.passportelementerror
|
||||
telegram.passportelementerrordatafield
|
||||
telegram.passportelementerrorfile
|
||||
telegram.passportelementerrorfiles
|
||||
telegram.passportelementerrorreverseside
|
||||
telegram.passportelementerrorfrontside
|
||||
telegram.passportelementerrordatafield
|
||||
telegram.passportelementerrorreverseside
|
||||
telegram.passportelementerrorselfie
|
||||
telegram.passportelementerrortranslationfile
|
||||
telegram.passportelementerrortranslationfiles
|
||||
telegram.passportelementerrorunspecified
|
||||
telegram.credentials
|
||||
telegram.datacredentials
|
||||
telegram.securedata
|
||||
telegram.securevalue
|
||||
telegram.filecredentials
|
||||
telegram.iddocumentdata
|
||||
telegram.passportfile
|
||||
telegram.personaldetails
|
||||
telegram.residentialaddress
|
||||
telegram.passportdata
|
||||
telegram.passportfile
|
||||
telegram.encryptedpassportelement
|
||||
telegram.encryptedcredentials
|
||||
telegram.securedata
|
||||
telegram.securevalue
|
||||
|
||||
+2
-58
@@ -1,61 +1,5 @@
|
||||
# Examples
|
||||
|
||||
In this folder are small examples to show what a bot written with `python-telegram-bot` looks like. Some bots focus on one specific aspect of the Telegram Bot API while others focus on one of the mechanics of this library. Except for the [`rawapibot.py`](#pure-api) example, they all use the high-level framework this library provides with the [`telegram.ext`](https://python-telegram-bot.readthedocs.io/en/latest/telegram.ext.html) submodule.
|
||||
A description of the examples in this directory can be found in the [documentation](https://docs.python-telegram-bot.org/examples.html).
|
||||
|
||||
All examples are licensed under the [CC0 License](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/LICENSE.txt) and are therefore fully dedicated to the public domain. You can use them as the base for your own bots without worrying about copyrights.
|
||||
|
||||
Do note that we ignore one pythonic convention. Best practice would dictate, in many handler callbacks function signatures, to replace the argument `context` with an underscore, since `context` is an unused local variable in those callbacks. However, since these are examples and not having a name for that argument confuses beginners, we decided to have it present.
|
||||
|
||||
### [`echobot.py`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/echobot.py)
|
||||
This is probably the base for most of the bots made with `python-telegram-bot`. It simply replies to each text message with a message that contains the same text.
|
||||
|
||||
### [`timerbot.py`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/timerbot.py)
|
||||
This bot uses the [`JobQueue`](https://python-telegram-bot.readthedocs.io/en/latest/telegram.ext.jobqueue.html) class to send timed messages. The user sets a timer by using `/set` command with a specific time, for example `/set 30`. The bot then sets up a job to send a message to that user after 30 seconds. The user can also cancel the timer by sending `/unset`. To learn more about the `JobQueue`, read [this wiki article](https://github.com/python-telegram-bot/python-telegram-bot/wiki/Extensions-%E2%80%93-JobQueue).
|
||||
|
||||
### [`conversationbot.py`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/conversationbot.py)
|
||||
A common task for a bot is to ask information from the user. In v5.0 of this library, we introduced the [`ConversationHandler`](https://python-telegram-bot.readthedocs.io/en/latest/telegram.ext.conversationhandler.html) for that exact purpose. This example uses it to retrieve user-information in a conversation-like style. To get a better understanding, take a look at the [state diagram](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/conversationbot.png).
|
||||
|
||||
### [`conversationbot2.py`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/conversationbot2.py)
|
||||
A more complex example of a bot that uses the `ConversationHandler`. It is also more confusing. Good thing there is a [fancy state diagram](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/conversationbot2.png) for this one, too!
|
||||
|
||||
### [`nestedconversationbot.py`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/nestedconversationbot.py)
|
||||
A even more complex example of a bot that uses the nested `ConversationHandler`s. While it's certainly not that complex that you couldn't built it without nested `ConversationHanldler`s, it gives a good impression on how to work with them. Of course, there is a [fancy state diagram](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/nestedconversationbot.png) for this example, too!
|
||||
|
||||
### [`persistentconversationbot.py`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/persistentconversationbot.py)
|
||||
A basic example of a bot store conversation state and user_data over multiple restarts.
|
||||
|
||||
### [`inlinekeyboard.py`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/inlinekeyboard.py)
|
||||
This example sheds some light on inline keyboards, callback queries and message editing. A wiki site explaining this examples lives [here](https://github.com/python-telegram-bot/python-telegram-bot/wiki/InlineKeyboard-Example).
|
||||
|
||||
### [`inlinekeyboard2.py`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/inlinekeyboard2.py)
|
||||
A more complex example about inline keyboards, callback queries and message editing. This example showcases how an interactive menu could be build using inline keyboards.
|
||||
|
||||
### [`deeplinking.py`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/deeplinking.py)
|
||||
A basic example on how to use deeplinking with inline keyboards.
|
||||
|
||||
### [`inlinebot.py`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/inlinebot.py)
|
||||
A basic example of an [inline bot](https://core.telegram.org/bots/inline). Don't forget to enable inline mode with [@BotFather](https://telegram.me/BotFather).
|
||||
|
||||
### [`pollbot.py`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/pollbot.py)
|
||||
This example sheds some light on polls, poll answers and the corresponding handlers.
|
||||
|
||||
### [`passportbot.py`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/passportbot.py)
|
||||
A basic example of a bot that can accept passports. Use in combination with [`passportbot.html`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/passportbot.html). Don't forget to enable and configure payments with [@BotFather](https://telegram.me/BotFather). Check out this [guide](https://github.com/python-telegram-bot/python-telegram-bot/wiki/Telegram-Passport) on Telegram passports in PTB.
|
||||
|
||||
### [`paymentbot.py`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/paymentbot.py)
|
||||
A basic example of a bot that can accept payments. Don't forget to enable and configure payments with [@BotFather](https://telegram.me/BotFather).
|
||||
|
||||
### [`errorhandlerbot.py`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/errorhandlerbot.py)
|
||||
A basic example on how to set up a custom error handler.
|
||||
|
||||
### [`chatmemberbot.py`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/chatmemberbot.py)
|
||||
A basic example on how `(my_)chat_member` updates can be used.
|
||||
|
||||
### [`contexttypesbot.py`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/contexttypesbot.py)
|
||||
This example showcases how `telegram.ext.ContextTypes` can be used to customize the `context` argument of handler and job callbacks.
|
||||
|
||||
### [`arbitrarycallbackdatabot.py`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/arbitrarycallbackdatabot.py)
|
||||
This example showcases how PTBs "arbitrary callback data" feature can be used.
|
||||
|
||||
## Pure API
|
||||
The [`rawapibot.py`](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/rawapibot.py) example uses only the pure, "bare-metal" API wrapper.
|
||||
All examples are licensed under the [CC0 License](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/LICENSE.txt) and are therefore fully dedicated to the public domain. You can use them as the base for your own bots without worrying about copyrights.
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=unused-argument
|
||||
# pylint: disable=unused-argument, wrong-import-position
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""This example showcases how PTBs "arbitrary callback data" feature can be used.
|
||||
@@ -10,12 +10,25 @@ https://github.com/python-telegram-bot/python-telegram-bot/wiki/Arbitrary-callba
|
||||
import logging
|
||||
from typing import List, Tuple, cast
|
||||
|
||||
from telegram import __version__ as TG_VER
|
||||
|
||||
try:
|
||||
from telegram import __version_info__
|
||||
except ImportError:
|
||||
__version_info__ = (0, 0, 0, 0, 0) # type: ignore[assignment]
|
||||
|
||||
if __version_info__ < (20, 0, 0, "alpha", 1):
|
||||
raise RuntimeError(
|
||||
f"This example is not compatible with your current PTB version {TG_VER}. To view the "
|
||||
f"{TG_VER} version of this example, "
|
||||
f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html"
|
||||
)
|
||||
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
|
||||
from telegram.ext import (
|
||||
Application,
|
||||
CallbackContext,
|
||||
CallbackQueryHandler,
|
||||
CommandHandler,
|
||||
ContextTypes,
|
||||
InvalidCallbackData,
|
||||
PicklePersistence,
|
||||
)
|
||||
@@ -27,13 +40,13 @@ logging.basicConfig(
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def start(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
|
||||
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Sends a message with 5 inline buttons attached."""
|
||||
number_list: List[int] = []
|
||||
await update.message.reply_text("Please choose:", reply_markup=build_keyboard(number_list))
|
||||
|
||||
|
||||
async def help_command(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
|
||||
async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Displays info on how to use the bot."""
|
||||
await update.message.reply_text(
|
||||
"Use /start to test this bot. Use /clear to clear the stored data so that you can see "
|
||||
@@ -41,7 +54,7 @@ async def help_command(update: Update, context: CallbackContext.DEFAULT_TYPE) ->
|
||||
)
|
||||
|
||||
|
||||
async def clear(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
|
||||
async def clear(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Clears the callback data cache"""
|
||||
context.bot.callback_data_cache.clear_callback_data()
|
||||
context.bot.callback_data_cache.clear_callback_queries()
|
||||
@@ -55,7 +68,7 @@ def build_keyboard(current_list: List[int]) -> InlineKeyboardMarkup:
|
||||
)
|
||||
|
||||
|
||||
async def list_button(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
|
||||
async def list_button(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Parses the CallbackQuery and updates the message text."""
|
||||
query = update.callback_query
|
||||
await query.answer()
|
||||
@@ -75,7 +88,7 @@ async def list_button(update: Update, context: CallbackContext.DEFAULT_TYPE) ->
|
||||
context.drop_callback_data(query)
|
||||
|
||||
|
||||
async def handle_invalid_button(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
|
||||
async def handle_invalid_button(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Informs the user that the button is no longer available."""
|
||||
await update.callback_query.answer()
|
||||
await update.effective_message.edit_text(
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=unused-argument
|
||||
# pylint: disable=unused-argument, wrong-import-position
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""
|
||||
@@ -14,9 +14,22 @@ bot.
|
||||
import logging
|
||||
from typing import Optional, Tuple
|
||||
|
||||
from telegram import __version__ as TG_VER
|
||||
|
||||
try:
|
||||
from telegram import __version_info__
|
||||
except ImportError:
|
||||
__version_info__ = (0, 0, 0, 0, 0) # type: ignore[assignment]
|
||||
|
||||
if __version_info__ < (20, 0, 0, "alpha", 1):
|
||||
raise RuntimeError(
|
||||
f"This example is not compatible with your current PTB version {TG_VER}. To view the "
|
||||
f"{TG_VER} version of this example, "
|
||||
f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html"
|
||||
)
|
||||
from telegram import Chat, ChatMember, ChatMemberUpdated, Update
|
||||
from telegram.constants import ParseMode
|
||||
from telegram.ext import Application, CallbackContext, ChatMemberHandler, CommandHandler
|
||||
from telegram.ext import Application, ChatMemberHandler, CommandHandler, ContextTypes
|
||||
|
||||
# Enable logging
|
||||
|
||||
@@ -27,9 +40,7 @@ logging.basicConfig(
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def extract_status_change(
|
||||
chat_member_update: ChatMemberUpdated,
|
||||
) -> Optional[Tuple[bool, bool]]:
|
||||
def extract_status_change(chat_member_update: ChatMemberUpdated) -> Optional[Tuple[bool, bool]]:
|
||||
"""Takes a ChatMemberUpdated instance and extracts whether the 'old_chat_member' was a member
|
||||
of the chat and whether the 'new_chat_member' is a member of the chat. Returns None, if
|
||||
the status didn't change.
|
||||
@@ -55,7 +66,7 @@ def extract_status_change(
|
||||
return was_member, is_member
|
||||
|
||||
|
||||
async def track_chats(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
|
||||
async def track_chats(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Tracks the chats the bot is in."""
|
||||
result = extract_status_change(update.my_chat_member)
|
||||
if result is None:
|
||||
@@ -90,7 +101,7 @@ async def track_chats(update: Update, context: CallbackContext.DEFAULT_TYPE) ->
|
||||
context.bot_data.setdefault("channel_ids", set()).discard(chat.id)
|
||||
|
||||
|
||||
async def show_chats(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
|
||||
async def show_chats(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Shows which chats the bot is in"""
|
||||
user_ids = ", ".join(str(uid) for uid in context.bot_data.setdefault("user_ids", set()))
|
||||
group_ids = ", ".join(str(gid) for gid in context.bot_data.setdefault("group_ids", set()))
|
||||
@@ -103,7 +114,7 @@ async def show_chats(update: Update, context: CallbackContext.DEFAULT_TYPE) -> N
|
||||
await update.effective_message.reply_text(text)
|
||||
|
||||
|
||||
async def greet_chat_members(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
|
||||
async def greet_chat_members(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Greets new users in chats and announces when someone leaves"""
|
||||
result = extract_status_change(update.chat_member)
|
||||
if result is None:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=unused-argument
|
||||
# pylint: disable=unused-argument, wrong-import-position
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""
|
||||
@@ -14,6 +14,19 @@ import logging
|
||||
from collections import defaultdict
|
||||
from typing import DefaultDict, Optional, Set
|
||||
|
||||
from telegram import __version__ as TG_VER
|
||||
|
||||
try:
|
||||
from telegram import __version_info__
|
||||
except ImportError:
|
||||
__version_info__ = (0, 0, 0, 0, 0) # type: ignore[assignment]
|
||||
|
||||
if __version_info__ < (20, 0, 0, "alpha", 1):
|
||||
raise RuntimeError(
|
||||
f"This example is not compatible with your current PTB version {TG_VER}. To view the "
|
||||
f"{TG_VER} version of this example, "
|
||||
f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html"
|
||||
)
|
||||
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
|
||||
from telegram.constants import ParseMode
|
||||
from telegram.ext import (
|
||||
@@ -44,8 +57,8 @@ class ChatData:
|
||||
class CustomContext(CallbackContext[ExtBot, dict, ChatData, dict]):
|
||||
"""Custom class for context."""
|
||||
|
||||
def __init__(self, application: Application):
|
||||
super().__init__(application=application)
|
||||
def __init__(self, application: Application, chat_id: int = None, user_id: int = None):
|
||||
super().__init__(application=application, chat_id=chat_id, user_id=user_id)
|
||||
self._message_id: Optional[int] = None
|
||||
|
||||
@property
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
flowchart TB
|
||||
%% Documentation: https://mermaid-js.github.io/mermaid/#/flowchart
|
||||
A(("/start")):::entryPoint -->|Hi! My name is Professor Bot...| B((GENDER)):::state
|
||||
B --> |"- Boy <br /> - Girl <br /> - Other"|C("(choice)"):::userInput
|
||||
C --> |I see! Please send me a photo...| D((PHOTO)):::state
|
||||
D --> E("/skip"):::userInput
|
||||
D --> F("(photo)"):::userInput
|
||||
E --> |I bet you look great!| G[\ /]:::userInput
|
||||
F --> |Gorgeous!| G[\ /]
|
||||
G --> |"Now, send me your location .."| H((LOCATION)):::state
|
||||
H --> I("/skip"):::userInput
|
||||
H --> J("(location)"):::userInput
|
||||
I --> |You seem a bit paranoid!| K[\" "/]:::userInput
|
||||
J --> |Maybe I can visit...| K
|
||||
K --> |"Tell me about yourself..."| L(("BIO")):::state
|
||||
L --> M("(text)"):::userInput
|
||||
M --> |"Thanks and bye!"| End(("END")):::termination
|
||||
classDef userInput fill:#2a5279, color:#ffffff, stroke:#ffffff
|
||||
classDef state fill:#222222, color:#ffffff, stroke:#ffffff
|
||||
classDef entryPoint fill:#009c11, stroke:#42FF57, color:#ffffff
|
||||
classDef termination fill:#bb0007, stroke:#E60109, color:#ffffff
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 82 KiB |
+23
-10
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=unused-argument
|
||||
# pylint: disable=unused-argument, wrong-import-position
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""
|
||||
@@ -16,11 +16,24 @@ bot.
|
||||
|
||||
import logging
|
||||
|
||||
from telegram import __version__ as TG_VER
|
||||
|
||||
try:
|
||||
from telegram import __version_info__
|
||||
except ImportError:
|
||||
__version_info__ = (0, 0, 0, 0, 0) # type: ignore[assignment]
|
||||
|
||||
if __version_info__ < (20, 0, 0, "alpha", 1):
|
||||
raise RuntimeError(
|
||||
f"This example is not compatible with your current PTB version {TG_VER}. To view the "
|
||||
f"{TG_VER} version of this example, "
|
||||
f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html"
|
||||
)
|
||||
from telegram import ReplyKeyboardMarkup, ReplyKeyboardRemove, Update
|
||||
from telegram.ext import (
|
||||
Application,
|
||||
CallbackContext,
|
||||
CommandHandler,
|
||||
ContextTypes,
|
||||
ConversationHandler,
|
||||
MessageHandler,
|
||||
filters,
|
||||
@@ -35,7 +48,7 @@ logger = logging.getLogger(__name__)
|
||||
GENDER, PHOTO, LOCATION, BIO = range(4)
|
||||
|
||||
|
||||
async def start(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
|
||||
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
|
||||
"""Starts the conversation and asks the user about their gender."""
|
||||
reply_keyboard = [["Boy", "Girl", "Other"]]
|
||||
|
||||
@@ -51,7 +64,7 @@ async def start(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
|
||||
return GENDER
|
||||
|
||||
|
||||
async def gender(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
|
||||
async def gender(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
|
||||
"""Stores the selected gender and asks for a photo."""
|
||||
user = update.message.from_user
|
||||
logger.info("Gender of %s: %s", user.first_name, update.message.text)
|
||||
@@ -64,7 +77,7 @@ async def gender(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
|
||||
return PHOTO
|
||||
|
||||
|
||||
async def photo(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
|
||||
async def photo(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
|
||||
"""Stores the photo and asks for a location."""
|
||||
user = update.message.from_user
|
||||
photo_file = await update.message.photo[-1].get_file()
|
||||
@@ -77,7 +90,7 @@ async def photo(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
|
||||
return LOCATION
|
||||
|
||||
|
||||
async def skip_photo(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
|
||||
async def skip_photo(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
|
||||
"""Skips the photo and asks for a location."""
|
||||
user = update.message.from_user
|
||||
logger.info("User %s did not send a photo.", user.first_name)
|
||||
@@ -88,7 +101,7 @@ async def skip_photo(update: Update, context: CallbackContext.DEFAULT_TYPE) -> i
|
||||
return LOCATION
|
||||
|
||||
|
||||
async def location(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
|
||||
async def location(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
|
||||
"""Stores the location and asks for some info about the user."""
|
||||
user = update.message.from_user
|
||||
user_location = update.message.location
|
||||
@@ -102,7 +115,7 @@ async def location(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int
|
||||
return BIO
|
||||
|
||||
|
||||
async def skip_location(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
|
||||
async def skip_location(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
|
||||
"""Skips the location and asks for info about the user."""
|
||||
user = update.message.from_user
|
||||
logger.info("User %s did not send a location.", user.first_name)
|
||||
@@ -113,7 +126,7 @@ async def skip_location(update: Update, context: CallbackContext.DEFAULT_TYPE) -
|
||||
return BIO
|
||||
|
||||
|
||||
async def bio(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
|
||||
async def bio(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
|
||||
"""Stores the info about the user and ends the conversation."""
|
||||
user = update.message.from_user
|
||||
logger.info("Bio of %s: %s", user.first_name, update.message.text)
|
||||
@@ -122,7 +135,7 @@ async def bio(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
|
||||
return ConversationHandler.END
|
||||
|
||||
|
||||
async def cancel(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
|
||||
async def cancel(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
|
||||
"""Cancels and ends the conversation."""
|
||||
user = update.message.from_user
|
||||
logger.info("User %s canceled the conversation.", user.first_name)
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
flowchart TB
|
||||
%% Documentation: https://mermaid-js.github.io/mermaid/#/flowchart
|
||||
A(("/start")):::entryPoint -->|Hi! My name is Doctor Botter...| B((CHOOSING)):::state
|
||||
B --> C("Something else..."):::userInput
|
||||
C --> |What category?| D((TYPING_CHOICE)):::state
|
||||
D --> E("(text)"):::userInput
|
||||
E --> |"[save choice] <br /> I'd love to hear about that!"| F((TYPING_REPLY)):::state
|
||||
F --> G("(text)"):::userInput
|
||||
G --> |"[save choice: text] <br /> Neat! <br /> (List of facts) <br /> More?"| B
|
||||
B --> H("- Age <br /> - Favourite colour <br /> - Number of siblings"):::userInput
|
||||
H --> |"[save choice] <br /> I'd love to hear about that!"| F
|
||||
B --> I("Done"):::userInput
|
||||
I --> |"I learned these facts about you: <br /> ..."| End(("END")):::termination
|
||||
classDef userInput fill:#2a5279, color:#ffffff, stroke:#ffffff
|
||||
classDef state fill:#222222, color:#ffffff, stroke:#ffffff
|
||||
classDef entryPoint fill:#009c11, stroke:#42FF57, color:#ffffff
|
||||
classDef termination fill:#bb0007, stroke:#E60109, color:#ffffff
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 82 KiB |
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=unused-argument
|
||||
# pylint: disable=unused-argument, wrong-import-position
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""
|
||||
@@ -17,11 +17,24 @@ bot.
|
||||
import logging
|
||||
from typing import Dict
|
||||
|
||||
from telegram import __version__ as TG_VER
|
||||
|
||||
try:
|
||||
from telegram import __version_info__
|
||||
except ImportError:
|
||||
__version_info__ = (0, 0, 0, 0, 0) # type: ignore[assignment]
|
||||
|
||||
if __version_info__ < (20, 0, 0, "alpha", 1):
|
||||
raise RuntimeError(
|
||||
f"This example is not compatible with your current PTB version {TG_VER}. To view the "
|
||||
f"{TG_VER} version of this example, "
|
||||
f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html"
|
||||
)
|
||||
from telegram import ReplyKeyboardMarkup, ReplyKeyboardRemove, Update
|
||||
from telegram.ext import (
|
||||
Application,
|
||||
CallbackContext,
|
||||
CommandHandler,
|
||||
ContextTypes,
|
||||
ConversationHandler,
|
||||
MessageHandler,
|
||||
filters,
|
||||
@@ -49,7 +62,7 @@ def facts_to_str(user_data: Dict[str, str]) -> str:
|
||||
return "\n".join(facts).join(["\n", "\n"])
|
||||
|
||||
|
||||
async def start(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
|
||||
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
|
||||
"""Start the conversation and ask user for input."""
|
||||
await update.message.reply_text(
|
||||
"Hi! My name is Doctor Botter. I will hold a more complex conversation with you. "
|
||||
@@ -60,7 +73,7 @@ async def start(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
|
||||
return CHOOSING
|
||||
|
||||
|
||||
async def regular_choice(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
|
||||
async def regular_choice(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
|
||||
"""Ask the user for info about the selected predefined choice."""
|
||||
text = update.message.text
|
||||
context.user_data["choice"] = text
|
||||
@@ -69,7 +82,7 @@ async def regular_choice(update: Update, context: CallbackContext.DEFAULT_TYPE)
|
||||
return TYPING_REPLY
|
||||
|
||||
|
||||
async def custom_choice(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
|
||||
async def custom_choice(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
|
||||
"""Ask the user for a description of a custom category."""
|
||||
await update.message.reply_text(
|
||||
'Alright, please send me the category first, for example "Most impressive skill"'
|
||||
@@ -78,7 +91,7 @@ async def custom_choice(update: Update, context: CallbackContext.DEFAULT_TYPE) -
|
||||
return TYPING_CHOICE
|
||||
|
||||
|
||||
async def received_information(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
|
||||
async def received_information(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
|
||||
"""Store info provided by user and ask for the next category."""
|
||||
user_data = context.user_data
|
||||
text = update.message.text
|
||||
@@ -96,7 +109,7 @@ async def received_information(update: Update, context: CallbackContext.DEFAULT_
|
||||
return CHOOSING
|
||||
|
||||
|
||||
async def done(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
|
||||
async def done(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
|
||||
"""Display the gathered info and end the conversation."""
|
||||
user_data = context.user_data
|
||||
if "choice" in user_data:
|
||||
|
||||
@@ -0,0 +1,192 @@
|
||||
#!/usr/bin/env python
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
# pylint: disable=import-error,wrong-import-position
|
||||
"""
|
||||
Simple example of a bot that uses a custom webhook setup and handles custom updates.
|
||||
For the custom webhook setup, the libraries `starlette` and `uvicorn` are used. Please install
|
||||
them as `pip install starlette~=0.20.0 uvicorn~=0.17.0`.
|
||||
Note that any other `asyncio` based web server framework can be used for a custom webhook setup
|
||||
just as well.
|
||||
|
||||
Usage:
|
||||
Set bot token, url, admin chat_id and port at the start of the `main` function.
|
||||
You may also need to change the `listen` value in the uvicorn configuration to match your setup.
|
||||
Press Ctrl-C on the command line or send a signal to the process to stop the bot.
|
||||
"""
|
||||
import asyncio
|
||||
import html
|
||||
import logging
|
||||
from dataclasses import dataclass
|
||||
from http import HTTPStatus
|
||||
|
||||
import uvicorn
|
||||
from starlette.applications import Starlette
|
||||
from starlette.requests import Request
|
||||
from starlette.responses import PlainTextResponse, Response
|
||||
from starlette.routing import Route
|
||||
|
||||
from telegram import __version__ as TG_VER
|
||||
|
||||
try:
|
||||
from telegram import __version_info__
|
||||
except ImportError:
|
||||
__version_info__ = (0, 0, 0, 0, 0) # type: ignore[assignment]
|
||||
|
||||
if __version_info__ < (20, 0, 0, "alpha", 1):
|
||||
raise RuntimeError(
|
||||
f"This example is not compatible with your current PTB version {TG_VER}. To view the "
|
||||
f"{TG_VER} version of this example, "
|
||||
f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html"
|
||||
)
|
||||
|
||||
from telegram import Update
|
||||
from telegram.constants import ParseMode
|
||||
from telegram.ext import (
|
||||
Application,
|
||||
CallbackContext,
|
||||
CommandHandler,
|
||||
ContextTypes,
|
||||
ExtBot,
|
||||
TypeHandler,
|
||||
)
|
||||
|
||||
# Enable logging
|
||||
logging.basicConfig(
|
||||
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", level=logging.INFO
|
||||
)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@dataclass
|
||||
class WebhookUpdate:
|
||||
"""Simple dataclass to wrap a custom update type"""
|
||||
|
||||
user_id: int
|
||||
payload: str
|
||||
|
||||
|
||||
class CustomContext(CallbackContext[ExtBot, dict, dict, dict]):
|
||||
"""
|
||||
Custom CallbackContext class that makes `user_data` available for updates of type
|
||||
`WebhookUpdate`.
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def from_update(
|
||||
cls,
|
||||
update: object,
|
||||
application: "Application",
|
||||
) -> "CustomContext":
|
||||
if isinstance(update, WebhookUpdate):
|
||||
return cls(application=application, user_id=update.user_id)
|
||||
return super().from_update(update, application)
|
||||
|
||||
|
||||
async def start(update: Update, context: CustomContext) -> None:
|
||||
"""Display a message with instructions on how to use this bot."""
|
||||
url = context.bot_data["url"]
|
||||
payload_url = html.escape(f"{url}/submitpayload?user_id=<your user id>&payload=<payload>")
|
||||
text = (
|
||||
f"To check if the bot is still running, call <code>{url}/healthcheck</code>.\n\n"
|
||||
f"To post a custom update, call <code>{payload_url}</code>."
|
||||
)
|
||||
await update.message.reply_html(text=text)
|
||||
|
||||
|
||||
async def webhook_update(update: WebhookUpdate, context: CustomContext) -> None:
|
||||
"""Callback that handles the custom updates."""
|
||||
chat_member = await context.bot.get_chat_member(chat_id=update.user_id, user_id=update.user_id)
|
||||
payloads = context.user_data.setdefault("payloads", [])
|
||||
payloads.append(update.payload)
|
||||
combined_payloads = "</code>\n• <code>".join(payloads)
|
||||
text = (
|
||||
f"The user {chat_member.user.mention_html()} has sent a new payload. "
|
||||
f"So far they have sent the following payloads: \n\n• <code>{combined_payloads}</code>"
|
||||
)
|
||||
await context.bot.send_message(
|
||||
chat_id=context.bot_data["admin_chat_id"], text=text, parse_mode=ParseMode.HTML
|
||||
)
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
"""Set up the application and a custom webserver."""
|
||||
url = "https://domain.tld"
|
||||
admin_chat_id = 123456
|
||||
port = 8000
|
||||
|
||||
context_types = ContextTypes(context=CustomContext)
|
||||
# Here we set updater to None because we want our custom webhook server to handle the updates
|
||||
# and hence we don't need an Updater instance
|
||||
application = (
|
||||
Application.builder().token("TOKEN").updater(None).context_types(context_types).build()
|
||||
)
|
||||
# save the values in `bot_data` such that we may easily access them in the callbacks
|
||||
application.bot_data["url"] = url
|
||||
application.bot_data["admin_chat_id"] = admin_chat_id
|
||||
|
||||
# register handlers
|
||||
application.add_handler(CommandHandler("start", start))
|
||||
application.add_handler(TypeHandler(type=WebhookUpdate, callback=webhook_update))
|
||||
|
||||
# Pass webhook settings to telegram
|
||||
await application.bot.set_webhook(url=f"{url}/telegram")
|
||||
|
||||
# Set up webserver
|
||||
async def telegram(request: Request) -> Response:
|
||||
"""Handle incoming Telegram updates by putting them into the `update_queue`"""
|
||||
await application.update_queue.put(
|
||||
Update.de_json(data=await request.json(), bot=application.bot)
|
||||
)
|
||||
return Response()
|
||||
|
||||
async def custom_updates(request: Request) -> PlainTextResponse:
|
||||
"""
|
||||
Handle incoming webhook updates by also putting them into the `update_queue` if
|
||||
the required parameters were passed correctly.
|
||||
"""
|
||||
try:
|
||||
user_id = int(request.query_params["user_id"])
|
||||
payload = request.query_params["payload"]
|
||||
except KeyError:
|
||||
return PlainTextResponse(
|
||||
status_code=HTTPStatus.BAD_REQUEST,
|
||||
content="Please pass both `user_id` and `payload` as query parameters.",
|
||||
)
|
||||
except ValueError:
|
||||
return PlainTextResponse(
|
||||
status_code=HTTPStatus.BAD_REQUEST,
|
||||
content="The `user_id` must be a string!",
|
||||
)
|
||||
|
||||
await application.update_queue.put(WebhookUpdate(user_id=user_id, payload=payload))
|
||||
return PlainTextResponse("Thank you for the submission! It's being forwarded.")
|
||||
|
||||
async def health(_: Request) -> PlainTextResponse:
|
||||
"""For the health endpoint, reply with a simple plain text message."""
|
||||
return PlainTextResponse(content="The bot is still running fine :)")
|
||||
|
||||
starlette_app = Starlette(
|
||||
routes=[
|
||||
Route("/telegram", telegram, methods=["POST"]),
|
||||
Route("/healthcheck", health, methods=["GET"]),
|
||||
Route("/submitpayload", custom_updates, methods=["POST", "GET"]),
|
||||
]
|
||||
)
|
||||
webserver = uvicorn.Server(
|
||||
config=uvicorn.Config(
|
||||
app=starlette_app,
|
||||
port=port,
|
||||
use_colors=False,
|
||||
host="127.0.0.1",
|
||||
)
|
||||
)
|
||||
|
||||
# Run application and webserver together
|
||||
async with application:
|
||||
await application.start()
|
||||
await webserver.serve()
|
||||
await application.stop()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
+21
-16
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=unused-argument
|
||||
# pylint: disable=unused-argument, wrong-import-position
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""Bot that explains Telegram's "Deep Linking Parameters" functionality.
|
||||
@@ -20,15 +20,22 @@ bot.
|
||||
|
||||
import logging
|
||||
|
||||
from telegram import __version__ as TG_VER
|
||||
|
||||
try:
|
||||
from telegram import __version_info__
|
||||
except ImportError:
|
||||
__version_info__ = (0, 0, 0, 0, 0) # type: ignore[assignment]
|
||||
|
||||
if __version_info__ < (20, 0, 0, "alpha", 1):
|
||||
raise RuntimeError(
|
||||
f"This example is not compatible with your current PTB version {TG_VER}. To view the "
|
||||
f"{TG_VER} version of this example, "
|
||||
f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html"
|
||||
)
|
||||
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update, helpers
|
||||
from telegram.constants import ParseMode
|
||||
from telegram.ext import (
|
||||
Application,
|
||||
CallbackContext,
|
||||
CallbackQueryHandler,
|
||||
CommandHandler,
|
||||
filters,
|
||||
)
|
||||
from telegram.ext import Application, CallbackQueryHandler, CommandHandler, ContextTypes, filters
|
||||
|
||||
# Enable logging
|
||||
logging.basicConfig(
|
||||
@@ -47,7 +54,7 @@ SO_COOL = "so-cool"
|
||||
KEYBOARD_CALLBACKDATA = "keyboard-callback-data"
|
||||
|
||||
|
||||
async def start(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
|
||||
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Send a deep-linked URL when the command /start is issued."""
|
||||
bot = context.bot
|
||||
url = helpers.create_deep_linked_url(bot.username, CHECK_THIS_OUT, group=True)
|
||||
@@ -55,7 +62,7 @@ async def start(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
|
||||
await update.message.reply_text(text)
|
||||
|
||||
|
||||
async def deep_linked_level_1(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
|
||||
async def deep_linked_level_1(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Reached through the CHECK_THIS_OUT payload"""
|
||||
bot = context.bot
|
||||
url = helpers.create_deep_linked_url(bot.username, SO_COOL)
|
||||
@@ -69,7 +76,7 @@ async def deep_linked_level_1(update: Update, context: CallbackContext.DEFAULT_T
|
||||
await update.message.reply_text(text, reply_markup=keyboard)
|
||||
|
||||
|
||||
async def deep_linked_level_2(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
|
||||
async def deep_linked_level_2(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Reached through the SO_COOL payload"""
|
||||
bot = context.bot
|
||||
url = helpers.create_deep_linked_url(bot.username, USING_ENTITIES)
|
||||
@@ -77,7 +84,7 @@ async def deep_linked_level_2(update: Update, context: CallbackContext.DEFAULT_T
|
||||
await update.message.reply_text(text, parse_mode=ParseMode.HTML, disable_web_page_preview=True)
|
||||
|
||||
|
||||
async def deep_linked_level_3(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
|
||||
async def deep_linked_level_3(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Reached through the USING_ENTITIES payload"""
|
||||
await update.message.reply_text(
|
||||
"It is also possible to make deep-linking using InlineKeyboardButtons.",
|
||||
@@ -87,16 +94,14 @@ async def deep_linked_level_3(update: Update, context: CallbackContext.DEFAULT_T
|
||||
)
|
||||
|
||||
|
||||
async def deep_link_level_3_callback(
|
||||
update: Update, context: CallbackContext.DEFAULT_TYPE
|
||||
) -> None:
|
||||
async def deep_link_level_3_callback(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Answers CallbackQuery with deeplinking url."""
|
||||
bot = context.bot
|
||||
url = helpers.create_deep_linked_url(bot.username, USING_KEYBOARD)
|
||||
await update.callback_query.answer(url=url)
|
||||
|
||||
|
||||
async def deep_linked_level_4(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
|
||||
async def deep_linked_level_4(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Reached through the USING_KEYBOARD payload"""
|
||||
payload = context.args
|
||||
await update.message.reply_text(
|
||||
|
||||
+18
-5
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=unused-argument
|
||||
# pylint: disable=unused-argument, wrong-import-position
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""
|
||||
@@ -17,8 +17,21 @@ bot.
|
||||
|
||||
import logging
|
||||
|
||||
from telegram import __version__ as TG_VER
|
||||
|
||||
try:
|
||||
from telegram import __version_info__
|
||||
except ImportError:
|
||||
__version_info__ = (0, 0, 0, 0, 0) # type: ignore[assignment]
|
||||
|
||||
if __version_info__ < (20, 0, 0, "alpha", 1):
|
||||
raise RuntimeError(
|
||||
f"This example is not compatible with your current PTB version {TG_VER}. To view the "
|
||||
f"{TG_VER} version of this example, "
|
||||
f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html"
|
||||
)
|
||||
from telegram import ForceReply, Update
|
||||
from telegram.ext import Application, CallbackContext, CommandHandler, MessageHandler, filters
|
||||
from telegram.ext import Application, CommandHandler, ContextTypes, MessageHandler, filters
|
||||
|
||||
# Enable logging
|
||||
logging.basicConfig(
|
||||
@@ -29,7 +42,7 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
# Define a few command handlers. These usually take the two arguments update and
|
||||
# context.
|
||||
async def start(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
|
||||
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Send a message when the command /start is issued."""
|
||||
user = update.effective_user
|
||||
await update.message.reply_html(
|
||||
@@ -38,12 +51,12 @@ async def start(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
|
||||
)
|
||||
|
||||
|
||||
async def help_command(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
|
||||
async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Send a message when the command /help is issued."""
|
||||
await update.message.reply_text("Help!")
|
||||
|
||||
|
||||
async def echo(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
|
||||
async def echo(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Echo the user message."""
|
||||
await update.message.reply_text(update.message.text)
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=unused-argument
|
||||
# pylint: disable=unused-argument, wrong-import-position
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""This is a very simple example on how one could implement a custom error handler."""
|
||||
@@ -8,9 +8,22 @@ import json
|
||||
import logging
|
||||
import traceback
|
||||
|
||||
from telegram import __version__ as TG_VER
|
||||
|
||||
try:
|
||||
from telegram import __version_info__
|
||||
except ImportError:
|
||||
__version_info__ = (0, 0, 0, 0, 0) # type: ignore[assignment]
|
||||
|
||||
if __version_info__ < (20, 0, 0, "alpha", 1):
|
||||
raise RuntimeError(
|
||||
f"This example is not compatible with your current PTB version {TG_VER}. To view the "
|
||||
f"{TG_VER} version of this example, "
|
||||
f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html"
|
||||
)
|
||||
from telegram import Update
|
||||
from telegram.constants import ParseMode
|
||||
from telegram.ext import Application, CallbackContext, CommandHandler
|
||||
from telegram.ext import Application, CommandHandler, ContextTypes
|
||||
|
||||
# Enable logging
|
||||
logging.basicConfig(
|
||||
@@ -23,7 +36,7 @@ logger = logging.getLogger(__name__)
|
||||
DEVELOPER_CHAT_ID = 123456789
|
||||
|
||||
|
||||
async def error_handler(update: object, context: CallbackContext.DEFAULT_TYPE) -> None:
|
||||
async def error_handler(update: object, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Log the error and send a telegram message to notify the developer."""
|
||||
# Log the error before we do anything else, so we can see it even if something breaks.
|
||||
logger.error(msg="Exception while handling an update:", exc_info=context.error)
|
||||
@@ -51,12 +64,12 @@ async def error_handler(update: object, context: CallbackContext.DEFAULT_TYPE) -
|
||||
)
|
||||
|
||||
|
||||
async def bad_command(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
|
||||
async def bad_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Raise an error to trigger the error handler."""
|
||||
await context.bot.wrong_method_name() # type: ignore[attr-defined]
|
||||
|
||||
|
||||
async def start(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
|
||||
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Displays info on how to trigger an error."""
|
||||
await update.effective_message.reply_html(
|
||||
"Use /bad_command to cause an error.\n"
|
||||
|
||||
+20
-5
@@ -1,8 +1,10 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=unused-argument
|
||||
# pylint: disable=unused-argument, wrong-import-position
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""
|
||||
Don't forget to enable inline mode with @BotFather
|
||||
|
||||
First, a few handler functions are defined. Then, those functions are passed to
|
||||
the Application and registered at their respective places.
|
||||
Then, the bot is started and runs until we press Ctrl-C on the command line.
|
||||
@@ -16,9 +18,22 @@ import logging
|
||||
from html import escape
|
||||
from uuid import uuid4
|
||||
|
||||
from telegram import __version__ as TG_VER
|
||||
|
||||
try:
|
||||
from telegram import __version_info__
|
||||
except ImportError:
|
||||
__version_info__ = (0, 0, 0, 0, 0) # type: ignore[assignment]
|
||||
|
||||
if __version_info__ < (20, 0, 0, "alpha", 1):
|
||||
raise RuntimeError(
|
||||
f"This example is not compatible with your current PTB version {TG_VER}. To view the "
|
||||
f"{TG_VER} version of this example, "
|
||||
f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html"
|
||||
)
|
||||
from telegram import InlineQueryResultArticle, InputTextMessageContent, Update
|
||||
from telegram.constants import ParseMode
|
||||
from telegram.ext import Application, CallbackContext, CommandHandler, InlineQueryHandler
|
||||
from telegram.ext import Application, CommandHandler, ContextTypes, InlineQueryHandler
|
||||
|
||||
# Enable logging
|
||||
logging.basicConfig(
|
||||
@@ -29,17 +44,17 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
# Define a few command handlers. These usually take the two arguments update and
|
||||
# context.
|
||||
async def start(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
|
||||
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Send a message when the command /start is issued."""
|
||||
await update.message.reply_text("Hi!")
|
||||
|
||||
|
||||
async def help_command(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
|
||||
async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Send a message when the command /help is issued."""
|
||||
await update.message.reply_text("Help!")
|
||||
|
||||
|
||||
async def inline_query(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
|
||||
async def inline_query(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Handle the inline query. This is run when you type: @botusername <query>"""
|
||||
query = update.inline_query.query
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=unused-argument
|
||||
# pylint: disable=unused-argument, wrong-import-position
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""
|
||||
@@ -8,8 +8,21 @@ Basic example for a bot that uses inline keyboards. For an in-depth explanation,
|
||||
"""
|
||||
import logging
|
||||
|
||||
from telegram import __version__ as TG_VER
|
||||
|
||||
try:
|
||||
from telegram import __version_info__
|
||||
except ImportError:
|
||||
__version_info__ = (0, 0, 0, 0, 0) # type: ignore[assignment]
|
||||
|
||||
if __version_info__ < (20, 0, 0, "alpha", 1):
|
||||
raise RuntimeError(
|
||||
f"This example is not compatible with your current PTB version {TG_VER}. To view the "
|
||||
f"{TG_VER} version of this example, "
|
||||
f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html"
|
||||
)
|
||||
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
|
||||
from telegram.ext import Application, CallbackContext, CallbackQueryHandler, CommandHandler
|
||||
from telegram.ext import Application, CallbackQueryHandler, CommandHandler, ContextTypes
|
||||
|
||||
# Enable logging
|
||||
logging.basicConfig(
|
||||
@@ -18,7 +31,7 @@ logging.basicConfig(
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def start(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
|
||||
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Sends a message with three inline buttons attached."""
|
||||
keyboard = [
|
||||
[
|
||||
@@ -33,7 +46,7 @@ async def start(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
|
||||
await update.message.reply_text("Please choose:", reply_markup=reply_markup)
|
||||
|
||||
|
||||
async def button(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
|
||||
async def button(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Parses the CallbackQuery and updates the message text."""
|
||||
query = update.callback_query
|
||||
|
||||
@@ -44,7 +57,7 @@ async def button(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
|
||||
await query.edit_message_text(text=f"Selected option: {query.data}")
|
||||
|
||||
|
||||
async def help_command(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
|
||||
async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Displays info on how to use the bot."""
|
||||
await update.message.reply_text("Use /start to test this bot.")
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=unused-argument
|
||||
# pylint: disable=unused-argument, wrong-import-position
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""Simple inline keyboard bot with multiple CallbackQueryHandlers.
|
||||
@@ -16,12 +16,25 @@ Press Ctrl-C on the command line to stop the bot.
|
||||
"""
|
||||
import logging
|
||||
|
||||
from telegram import __version__ as TG_VER
|
||||
|
||||
try:
|
||||
from telegram import __version_info__
|
||||
except ImportError:
|
||||
__version_info__ = (0, 0, 0, 0, 0) # type: ignore[assignment]
|
||||
|
||||
if __version_info__ < (20, 0, 0, "alpha", 1):
|
||||
raise RuntimeError(
|
||||
f"This example is not compatible with your current PTB version {TG_VER}. To view the "
|
||||
f"{TG_VER} version of this example, "
|
||||
f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html"
|
||||
)
|
||||
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
|
||||
from telegram.ext import (
|
||||
Application,
|
||||
CallbackContext,
|
||||
CallbackQueryHandler,
|
||||
CommandHandler,
|
||||
ContextTypes,
|
||||
ConversationHandler,
|
||||
)
|
||||
|
||||
@@ -37,7 +50,7 @@ START_ROUTES, END_ROUTES = range(2)
|
||||
ONE, TWO, THREE, FOUR = range(4)
|
||||
|
||||
|
||||
async def start(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
|
||||
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
|
||||
"""Send message on `/start`."""
|
||||
# Get user that sent /start and log his name
|
||||
user = update.message.from_user
|
||||
@@ -59,7 +72,7 @@ async def start(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
|
||||
return START_ROUTES
|
||||
|
||||
|
||||
async def start_over(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
|
||||
async def start_over(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
|
||||
"""Prompt same text & keyboard as `start` does but not as new message"""
|
||||
# Get CallbackQuery from Update
|
||||
query = update.callback_query
|
||||
@@ -80,7 +93,7 @@ async def start_over(update: Update, context: CallbackContext.DEFAULT_TYPE) -> i
|
||||
return START_ROUTES
|
||||
|
||||
|
||||
async def one(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
|
||||
async def one(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
|
||||
"""Show new choice of buttons"""
|
||||
query = update.callback_query
|
||||
await query.answer()
|
||||
@@ -97,7 +110,7 @@ async def one(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
|
||||
return START_ROUTES
|
||||
|
||||
|
||||
async def two(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
|
||||
async def two(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
|
||||
"""Show new choice of buttons"""
|
||||
query = update.callback_query
|
||||
await query.answer()
|
||||
@@ -114,7 +127,7 @@ async def two(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
|
||||
return START_ROUTES
|
||||
|
||||
|
||||
async def three(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
|
||||
async def three(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
|
||||
"""Show new choice of buttons. This is the end point of the conversation."""
|
||||
query = update.callback_query
|
||||
await query.answer()
|
||||
@@ -132,7 +145,7 @@ async def three(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
|
||||
return END_ROUTES
|
||||
|
||||
|
||||
async def four(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
|
||||
async def four(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
|
||||
"""Show new choice of buttons"""
|
||||
query = update.callback_query
|
||||
await query.answer()
|
||||
@@ -149,7 +162,7 @@ async def four(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
|
||||
return START_ROUTES
|
||||
|
||||
|
||||
async def end(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
|
||||
async def end(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
|
||||
"""Returns `ConversationHandler.END`, which tells the
|
||||
ConversationHandler that the conversation is over.
|
||||
"""
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
flowchart TB
|
||||
%% Documentation: https://mermaid-js.github.io/mermaid/#/flowchart
|
||||
A(("/start")):::entryPoint -->|Hi! I'm FamilyBot...| B((SELECTING_ACTION)):::state
|
||||
B --> C("Show Data"):::userInput
|
||||
C --> |"(List of gathered data)"| D((SHOWING)):::state
|
||||
D --> E("Back"):::userInput
|
||||
E --> B
|
||||
B --> F("Add Yourself"):::userInput
|
||||
F --> G(("DESCRIBING_SELF")):::state
|
||||
G --> H("Add info"):::userInput
|
||||
H --> I((SELECT_FEATURE)):::state
|
||||
I --> |"Please select a feature to update. <br /> - Name <br /> - Age <br /> - Done"|J("(choice)"):::userInput
|
||||
J --> |"Okay, tell me."| K((TYPING)):::state
|
||||
K --> L("(text)"):::userInput
|
||||
L --> |"[saving]"|I
|
||||
I --> M("Done"):::userInput
|
||||
M --> B
|
||||
B --> N("Add family member"):::userInput
|
||||
R --> I
|
||||
W --> |"See you around!"|End(("END")):::termination
|
||||
Y(("ANY STATE")):::state --> Z("/stop"):::userInput
|
||||
Z -->|"Okay, bye."| End
|
||||
B --> W("Done"):::userInput
|
||||
subgraph nestedConversation[Nested Conversation: Add Family Member]
|
||||
direction BT
|
||||
N --> O(("SELECT_LEVEL")):::state
|
||||
O --> |"Add... <br /> - Add Parent <br /> - Add Child <br />"|P("(choice)"):::userInput
|
||||
P --> Q(("SELECT_GENDER")):::state
|
||||
Q --> |"- Mother <br /> - Father <br /> / <br /> - Sister <br /> - Brother"| R("(choice)"):::userInput
|
||||
Q --> V("Show Data"):::userInput
|
||||
Q --> T(("SELECTING_ACTION")):::state
|
||||
Q --> U("Back"):::userInput
|
||||
U --> T
|
||||
O --> U
|
||||
O --> V
|
||||
V --> S(("SHOWING")):::state
|
||||
V --> T
|
||||
end
|
||||
classDef userInput fill:#2a5279, color:#ffffff, stroke:#ffffff
|
||||
classDef state fill:#222222, color:#ffffff, stroke:#ffffff
|
||||
classDef entryPoint fill:#009c11, stroke:#42FF57, color:#ffffff
|
||||
classDef termination fill:#bb0007, stroke:#E60109, color:#ffffff
|
||||
style nestedConversation fill:#999999, stroke-width:2px, stroke:#333333
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 492 KiB |
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=unused-argument
|
||||
# pylint: disable=unused-argument, wrong-import-position
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""
|
||||
@@ -17,12 +17,25 @@ bot.
|
||||
import logging
|
||||
from typing import Any, Dict, Tuple
|
||||
|
||||
from telegram import __version__ as TG_VER
|
||||
|
||||
try:
|
||||
from telegram import __version_info__
|
||||
except ImportError:
|
||||
__version_info__ = (0, 0, 0, 0, 0) # type: ignore[assignment]
|
||||
|
||||
if __version_info__ < (20, 0, 0, "alpha", 1):
|
||||
raise RuntimeError(
|
||||
f"This example is not compatible with your current PTB version {TG_VER}. To view the "
|
||||
f"{TG_VER} version of this example, "
|
||||
f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html"
|
||||
)
|
||||
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
|
||||
from telegram.ext import (
|
||||
Application,
|
||||
CallbackContext,
|
||||
CallbackQueryHandler,
|
||||
CommandHandler,
|
||||
ContextTypes,
|
||||
ConversationHandler,
|
||||
MessageHandler,
|
||||
filters,
|
||||
@@ -70,7 +83,7 @@ def _name_switcher(level: str) -> Tuple[str, str]:
|
||||
|
||||
|
||||
# Top level conversation callbacks
|
||||
async def start(update: Update, context: CallbackContext.DEFAULT_TYPE) -> str:
|
||||
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> str:
|
||||
"""Select an action: Adding parent/child or show data."""
|
||||
text = (
|
||||
"You may choose to add a family member, yourself, show the gathered data, or end the "
|
||||
@@ -103,7 +116,7 @@ async def start(update: Update, context: CallbackContext.DEFAULT_TYPE) -> str:
|
||||
return SELECTING_ACTION
|
||||
|
||||
|
||||
async def adding_self(update: Update, context: CallbackContext.DEFAULT_TYPE) -> str:
|
||||
async def adding_self(update: Update, context: ContextTypes.DEFAULT_TYPE) -> str:
|
||||
"""Add information about yourself."""
|
||||
context.user_data[CURRENT_LEVEL] = SELF
|
||||
text = "Okay, please tell me about yourself."
|
||||
@@ -116,7 +129,7 @@ async def adding_self(update: Update, context: CallbackContext.DEFAULT_TYPE) ->
|
||||
return DESCRIBING_SELF
|
||||
|
||||
|
||||
async def show_data(update: Update, context: CallbackContext.DEFAULT_TYPE) -> str:
|
||||
async def show_data(update: Update, context: ContextTypes.DEFAULT_TYPE) -> str:
|
||||
"""Pretty print gathered data."""
|
||||
|
||||
def pretty_print(data: Dict[str, Any], level: str) -> str:
|
||||
@@ -153,14 +166,14 @@ async def show_data(update: Update, context: CallbackContext.DEFAULT_TYPE) -> st
|
||||
return SHOWING
|
||||
|
||||
|
||||
async def stop(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
|
||||
async def stop(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
|
||||
"""End Conversation by command."""
|
||||
await update.message.reply_text("Okay, bye.")
|
||||
|
||||
return END
|
||||
|
||||
|
||||
async def end(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
|
||||
async def end(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
|
||||
"""End conversation from InlineKeyboardButton."""
|
||||
await update.callback_query.answer()
|
||||
|
||||
@@ -171,7 +184,7 @@ async def end(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
|
||||
|
||||
|
||||
# Second level conversation callbacks
|
||||
async def select_level(update: Update, context: CallbackContext.DEFAULT_TYPE) -> str:
|
||||
async def select_level(update: Update, context: ContextTypes.DEFAULT_TYPE) -> str:
|
||||
"""Choose to add a parent or a child."""
|
||||
text = "You may add a parent or a child. Also you can show the gathered data or go back."
|
||||
buttons = [
|
||||
@@ -192,7 +205,7 @@ async def select_level(update: Update, context: CallbackContext.DEFAULT_TYPE) ->
|
||||
return SELECTING_LEVEL
|
||||
|
||||
|
||||
async def select_gender(update: Update, context: CallbackContext.DEFAULT_TYPE) -> str:
|
||||
async def select_gender(update: Update, context: ContextTypes.DEFAULT_TYPE) -> str:
|
||||
"""Choose to add mother or father."""
|
||||
level = update.callback_query.data
|
||||
context.user_data[CURRENT_LEVEL] = level
|
||||
@@ -219,7 +232,7 @@ async def select_gender(update: Update, context: CallbackContext.DEFAULT_TYPE) -
|
||||
return SELECTING_GENDER
|
||||
|
||||
|
||||
async def end_second_level(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
|
||||
async def end_second_level(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
|
||||
"""Return to top level conversation."""
|
||||
context.user_data[START_OVER] = True
|
||||
await start(update, context)
|
||||
@@ -228,7 +241,7 @@ async def end_second_level(update: Update, context: CallbackContext.DEFAULT_TYPE
|
||||
|
||||
|
||||
# Third level callbacks
|
||||
async def select_feature(update: Update, context: CallbackContext.DEFAULT_TYPE) -> str:
|
||||
async def select_feature(update: Update, context: ContextTypes.DEFAULT_TYPE) -> str:
|
||||
"""Select a feature to update for the person."""
|
||||
buttons = [
|
||||
[
|
||||
@@ -255,7 +268,7 @@ async def select_feature(update: Update, context: CallbackContext.DEFAULT_TYPE)
|
||||
return SELECTING_FEATURE
|
||||
|
||||
|
||||
async def ask_for_input(update: Update, context: CallbackContext.DEFAULT_TYPE) -> str:
|
||||
async def ask_for_input(update: Update, context: ContextTypes.DEFAULT_TYPE) -> str:
|
||||
"""Prompt user to input data for selected feature."""
|
||||
context.user_data[CURRENT_FEATURE] = update.callback_query.data
|
||||
text = "Okay, tell me."
|
||||
@@ -266,7 +279,7 @@ async def ask_for_input(update: Update, context: CallbackContext.DEFAULT_TYPE) -
|
||||
return TYPING
|
||||
|
||||
|
||||
async def save_input(update: Update, context: CallbackContext.DEFAULT_TYPE) -> str:
|
||||
async def save_input(update: Update, context: ContextTypes.DEFAULT_TYPE) -> str:
|
||||
"""Save input for feature and return to feature selection."""
|
||||
user_data = context.user_data
|
||||
user_data[FEATURES][user_data[CURRENT_FEATURE]] = update.message.text
|
||||
@@ -276,7 +289,7 @@ async def save_input(update: Update, context: CallbackContext.DEFAULT_TYPE) -> s
|
||||
return await select_feature(update, context)
|
||||
|
||||
|
||||
async def end_describing(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
|
||||
async def end_describing(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
|
||||
"""End gathering of features and return to parent conversation."""
|
||||
user_data = context.user_data
|
||||
level = user_data[CURRENT_LEVEL]
|
||||
@@ -294,7 +307,7 @@ async def end_describing(update: Update, context: CallbackContext.DEFAULT_TYPE)
|
||||
return END
|
||||
|
||||
|
||||
async def stop_nested(update: Update, context: CallbackContext.DEFAULT_TYPE) -> str:
|
||||
async def stop_nested(update: Update, context: ContextTypes.DEFAULT_TYPE) -> str:
|
||||
"""Completely end conversation from within nested conversation."""
|
||||
await update.message.reply_text("Okay, bye.")
|
||||
|
||||
|
||||
+16
-3
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=unused-argument
|
||||
# pylint: disable=unused-argument, wrong-import-position
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""
|
||||
@@ -14,8 +14,21 @@ See https://github.com/python-telegram-bot/python-telegram-bot/wiki/Telegram-Pas
|
||||
import logging
|
||||
from pathlib import Path
|
||||
|
||||
from telegram import __version__ as TG_VER
|
||||
|
||||
try:
|
||||
from telegram import __version_info__
|
||||
except ImportError:
|
||||
__version_info__ = (0, 0, 0, 0, 0) # type: ignore[assignment]
|
||||
|
||||
if __version_info__ < (20, 0, 0, "alpha", 1):
|
||||
raise RuntimeError(
|
||||
f"This example is not compatible with your current PTB version {TG_VER}. To view the "
|
||||
f"{TG_VER} version of this example, "
|
||||
f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html"
|
||||
)
|
||||
from telegram import Update
|
||||
from telegram.ext import Application, CallbackContext, MessageHandler, filters
|
||||
from telegram.ext import Application, ContextTypes, MessageHandler, filters
|
||||
|
||||
# Enable logging
|
||||
|
||||
@@ -26,7 +39,7 @@ logging.basicConfig(
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def msg(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
|
||||
async def msg(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Downloads and prints the received passport data."""
|
||||
# Retrieve passport data
|
||||
passport_data = update.message.passport_data
|
||||
|
||||
+21
-12
@@ -1,16 +1,29 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=unused-argument
|
||||
# pylint: disable=unused-argument, wrong-import-position
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""Basic example for a bot that can receive payment from user."""
|
||||
|
||||
import logging
|
||||
|
||||
from telegram import __version__ as TG_VER
|
||||
|
||||
try:
|
||||
from telegram import __version_info__
|
||||
except ImportError:
|
||||
__version_info__ = (0, 0, 0, 0, 0) # type: ignore[assignment]
|
||||
|
||||
if __version_info__ < (20, 0, 0, "alpha", 1):
|
||||
raise RuntimeError(
|
||||
f"This example is not compatible with your current PTB version {TG_VER}. To view the "
|
||||
f"{TG_VER} version of this example, "
|
||||
f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html"
|
||||
)
|
||||
from telegram import LabeledPrice, ShippingOption, Update
|
||||
from telegram.ext import (
|
||||
Application,
|
||||
CallbackContext,
|
||||
CommandHandler,
|
||||
ContextTypes,
|
||||
MessageHandler,
|
||||
PreCheckoutQueryHandler,
|
||||
ShippingQueryHandler,
|
||||
@@ -26,7 +39,7 @@ logger = logging.getLogger(__name__)
|
||||
PAYMENT_PROVIDER_TOKEN = "PAYMENT_PROVIDER_TOKEN"
|
||||
|
||||
|
||||
async def start_callback(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
|
||||
async def start_callback(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Displays info on how to use the bot."""
|
||||
msg = (
|
||||
"Use /shipping to get an invoice for shipping-payment, or /noshipping for an "
|
||||
@@ -36,9 +49,7 @@ async def start_callback(update: Update, context: CallbackContext.DEFAULT_TYPE)
|
||||
await update.message.reply_text(msg)
|
||||
|
||||
|
||||
async def start_with_shipping_callback(
|
||||
update: Update, context: CallbackContext.DEFAULT_TYPE
|
||||
) -> None:
|
||||
async def start_with_shipping_callback(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Sends an invoice with shipping-payment."""
|
||||
chat_id = update.message.chat_id
|
||||
title = "Payment Example"
|
||||
@@ -72,7 +83,7 @@ async def start_with_shipping_callback(
|
||||
|
||||
|
||||
async def start_without_shipping_callback(
|
||||
update: Update, context: CallbackContext.DEFAULT_TYPE
|
||||
update: Update, context: ContextTypes.DEFAULT_TYPE
|
||||
) -> None:
|
||||
"""Sends an invoice without shipping-payment."""
|
||||
chat_id = update.message.chat_id
|
||||
@@ -94,7 +105,7 @@ async def start_without_shipping_callback(
|
||||
)
|
||||
|
||||
|
||||
async def shipping_callback(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
|
||||
async def shipping_callback(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Answers the ShippingQuery with ShippingOptions"""
|
||||
query = update.shipping_query
|
||||
# check the payload, is this from your bot?
|
||||
@@ -112,7 +123,7 @@ async def shipping_callback(update: Update, context: CallbackContext.DEFAULT_TYP
|
||||
|
||||
|
||||
# after (optional) shipping, it's the pre-checkout
|
||||
async def precheckout_callback(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
|
||||
async def precheckout_callback(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Answers the PreQecheckoutQuery"""
|
||||
query = update.pre_checkout_query
|
||||
# check the payload, is this from your bot?
|
||||
@@ -124,9 +135,7 @@ async def precheckout_callback(update: Update, context: CallbackContext.DEFAULT_
|
||||
|
||||
|
||||
# finally, after contacting the payment provider...
|
||||
async def successful_payment_callback(
|
||||
update: Update, context: CallbackContext.DEFAULT_TYPE
|
||||
) -> None:
|
||||
async def successful_payment_callback(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Confirms the successful payment."""
|
||||
# do something after successfully receiving payment?
|
||||
await update.message.reply_text("Thank you for your payment!")
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=unused-argument
|
||||
# pylint: disable=unused-argument, wrong-import-position
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""
|
||||
@@ -17,11 +17,24 @@ bot.
|
||||
import logging
|
||||
from typing import Dict
|
||||
|
||||
from telegram import __version__ as TG_VER
|
||||
|
||||
try:
|
||||
from telegram import __version_info__
|
||||
except ImportError:
|
||||
__version_info__ = (0, 0, 0, 0, 0) # type: ignore[assignment]
|
||||
|
||||
if __version_info__ < (20, 0, 0, "alpha", 1):
|
||||
raise RuntimeError(
|
||||
f"This example is not compatible with your current PTB version {TG_VER}. To view the "
|
||||
f"{TG_VER} version of this example, "
|
||||
f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html"
|
||||
)
|
||||
from telegram import ReplyKeyboardMarkup, ReplyKeyboardRemove, Update
|
||||
from telegram.ext import (
|
||||
Application,
|
||||
CallbackContext,
|
||||
CommandHandler,
|
||||
ContextTypes,
|
||||
ConversationHandler,
|
||||
MessageHandler,
|
||||
PicklePersistence,
|
||||
@@ -50,7 +63,7 @@ def facts_to_str(user_data: Dict[str, str]) -> str:
|
||||
return "\n".join(facts).join(["\n", "\n"])
|
||||
|
||||
|
||||
async def start(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
|
||||
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
|
||||
"""Start the conversation, display any stored data and ask user for input."""
|
||||
reply_text = "Hi! My name is Doctor Botter."
|
||||
if context.user_data:
|
||||
@@ -68,7 +81,7 @@ async def start(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
|
||||
return CHOOSING
|
||||
|
||||
|
||||
async def regular_choice(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
|
||||
async def regular_choice(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
|
||||
"""Ask the user for info about the selected predefined choice."""
|
||||
text = update.message.text.lower()
|
||||
context.user_data["choice"] = text
|
||||
@@ -83,7 +96,7 @@ async def regular_choice(update: Update, context: CallbackContext.DEFAULT_TYPE)
|
||||
return TYPING_REPLY
|
||||
|
||||
|
||||
async def custom_choice(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
|
||||
async def custom_choice(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
|
||||
"""Ask the user for a description of a custom category."""
|
||||
await update.message.reply_text(
|
||||
'Alright, please send me the category first, for example "Most impressive skill"'
|
||||
@@ -92,7 +105,7 @@ async def custom_choice(update: Update, context: CallbackContext.DEFAULT_TYPE) -
|
||||
return TYPING_CHOICE
|
||||
|
||||
|
||||
async def received_information(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
|
||||
async def received_information(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
|
||||
"""Store info provided by user and ask for the next category."""
|
||||
text = update.message.text
|
||||
category = context.user_data["choice"]
|
||||
@@ -109,14 +122,14 @@ async def received_information(update: Update, context: CallbackContext.DEFAULT_
|
||||
return CHOOSING
|
||||
|
||||
|
||||
async def show_data(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
|
||||
async def show_data(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Display the gathered info."""
|
||||
await update.message.reply_text(
|
||||
f"This is what you already told me: {facts_to_str(context.user_data)}"
|
||||
)
|
||||
|
||||
|
||||
async def done(update: Update, context: CallbackContext.DEFAULT_TYPE) -> int:
|
||||
async def done(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
|
||||
"""Display the gathered info and end the conversation."""
|
||||
if "choice" in context.user_data:
|
||||
del context.user_data["choice"]
|
||||
|
||||
+23
-10
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=unused-argument
|
||||
# pylint: disable=unused-argument, wrong-import-position
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""
|
||||
@@ -9,6 +9,19 @@ one the user sends the bot
|
||||
"""
|
||||
import logging
|
||||
|
||||
from telegram import __version__ as TG_VER
|
||||
|
||||
try:
|
||||
from telegram import __version_info__
|
||||
except ImportError:
|
||||
__version_info__ = (0, 0, 0, 0, 0) # type: ignore[assignment]
|
||||
|
||||
if __version_info__ < (20, 0, 0, "alpha", 1):
|
||||
raise RuntimeError(
|
||||
f"This example is not compatible with your current PTB version {TG_VER}. To view the "
|
||||
f"{TG_VER} version of this example, "
|
||||
f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html"
|
||||
)
|
||||
from telegram import (
|
||||
KeyboardButton,
|
||||
KeyboardButtonPollType,
|
||||
@@ -20,8 +33,8 @@ from telegram import (
|
||||
from telegram.constants import ParseMode
|
||||
from telegram.ext import (
|
||||
Application,
|
||||
CallbackContext,
|
||||
CommandHandler,
|
||||
ContextTypes,
|
||||
MessageHandler,
|
||||
PollAnswerHandler,
|
||||
PollHandler,
|
||||
@@ -35,7 +48,7 @@ logging.basicConfig(
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def start(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
|
||||
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Inform user about what this bot can do"""
|
||||
await update.message.reply_text(
|
||||
"Please select /poll to get a Poll, /quiz to get a Quiz or /preview"
|
||||
@@ -43,7 +56,7 @@ async def start(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
|
||||
)
|
||||
|
||||
|
||||
async def poll(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
|
||||
async def poll(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Sends a predefined poll"""
|
||||
questions = ["Good", "Really good", "Fantastic", "Great"]
|
||||
message = await context.bot.send_poll(
|
||||
@@ -65,7 +78,7 @@ async def poll(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
|
||||
context.bot_data.update(payload)
|
||||
|
||||
|
||||
async def receive_poll_answer(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
|
||||
async def receive_poll_answer(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Summarize a users poll vote"""
|
||||
answer = update.poll_answer
|
||||
answered_poll = context.bot_data[answer.poll_id]
|
||||
@@ -92,7 +105,7 @@ async def receive_poll_answer(update: Update, context: CallbackContext.DEFAULT_T
|
||||
await context.bot.stop_poll(answered_poll["chat_id"], answered_poll["message_id"])
|
||||
|
||||
|
||||
async def quiz(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
|
||||
async def quiz(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Send a predefined poll"""
|
||||
questions = ["1", "2", "4", "20"]
|
||||
message = await update.effective_message.reply_poll(
|
||||
@@ -105,7 +118,7 @@ async def quiz(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
|
||||
context.bot_data.update(payload)
|
||||
|
||||
|
||||
async def receive_quiz_answer(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
|
||||
async def receive_quiz_answer(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Close quiz after three participants took it"""
|
||||
# the bot can receive closed poll updates we don't care about
|
||||
if update.poll.is_closed:
|
||||
@@ -119,7 +132,7 @@ async def receive_quiz_answer(update: Update, context: CallbackContext.DEFAULT_T
|
||||
await context.bot.stop_poll(quiz_data["chat_id"], quiz_data["message_id"])
|
||||
|
||||
|
||||
async def preview(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
|
||||
async def preview(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Ask user to create a poll and display a preview of it"""
|
||||
# using this without a type lets the user chooses what he wants (quiz or poll)
|
||||
button = [[KeyboardButton("Press me!", request_poll=KeyboardButtonPollType())]]
|
||||
@@ -130,7 +143,7 @@ async def preview(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None
|
||||
)
|
||||
|
||||
|
||||
async def receive_poll(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
|
||||
async def receive_poll(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""On receiving polls, reply to it by a closed poll copying the received poll"""
|
||||
actual_poll = update.effective_message.poll
|
||||
# Only need to set the question and options, since all other parameters don't matter for
|
||||
@@ -144,7 +157,7 @@ async def receive_poll(update: Update, context: CallbackContext.DEFAULT_TYPE) ->
|
||||
)
|
||||
|
||||
|
||||
async def help_handler(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
|
||||
async def help_handler(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Display a help message"""
|
||||
await update.message.reply_text("Use /quiz, /poll or /preview to test this bot.")
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=wrong-import-position
|
||||
"""Simple Bot to reply to Telegram messages.
|
||||
|
||||
This is built on the API wrapper, see echobot.py to see the same example built
|
||||
@@ -9,6 +10,19 @@ import asyncio
|
||||
import logging
|
||||
from typing import NoReturn
|
||||
|
||||
from telegram import __version__ as TG_VER
|
||||
|
||||
try:
|
||||
from telegram import __version_info__
|
||||
except ImportError:
|
||||
__version_info__ = (0, 0, 0, 0, 0) # type: ignore[assignment] # type: ignore[assignment]
|
||||
|
||||
if __version_info__ < (20, 0, 0, "alpha", 1):
|
||||
raise RuntimeError(
|
||||
f"This example is not compatible with your current PTB version {TG_VER}. To view the "
|
||||
f"{TG_VER} version of this example, "
|
||||
f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html"
|
||||
)
|
||||
from telegram import Bot
|
||||
from telegram.error import Forbidden, NetworkError
|
||||
|
||||
|
||||
+25
-12
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=unused-argument
|
||||
# pylint: disable=unused-argument, wrong-import-position
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""
|
||||
@@ -20,8 +20,21 @@ bot.
|
||||
|
||||
import logging
|
||||
|
||||
from telegram import __version__ as TG_VER
|
||||
|
||||
try:
|
||||
from telegram import __version_info__
|
||||
except ImportError:
|
||||
__version_info__ = (0, 0, 0, 0, 0) # type: ignore[assignment]
|
||||
|
||||
if __version_info__ < (20, 0, 0, "alpha", 1):
|
||||
raise RuntimeError(
|
||||
f"This example is not compatible with your current PTB version {TG_VER}. To view the "
|
||||
f"{TG_VER} version of this example, "
|
||||
f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html"
|
||||
)
|
||||
from telegram import Update
|
||||
from telegram.ext import Application, CallbackContext, CommandHandler
|
||||
from telegram.ext import Application, CommandHandler, ContextTypes
|
||||
|
||||
# Enable logging
|
||||
logging.basicConfig(
|
||||
@@ -35,18 +48,18 @@ logging.basicConfig(
|
||||
# since context is an unused local variable.
|
||||
# This being an example and not having context present confusing beginners,
|
||||
# we decided to have it present as context.
|
||||
async def start(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
|
||||
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Sends explanation on how to use the bot."""
|
||||
await update.message.reply_text("Hi! Use /set <seconds> to set a timer")
|
||||
|
||||
|
||||
async def alarm(context: CallbackContext.DEFAULT_TYPE) -> None:
|
||||
async def alarm(context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Send the alarm message."""
|
||||
job = context.job
|
||||
await context.bot.send_message(job.chat_id, text=f"Beep! {job.context} seconds are over!")
|
||||
await context.bot.send_message(job.chat_id, text=f"Beep! {job.data} seconds are over!")
|
||||
|
||||
|
||||
def remove_job_if_exists(name: str, context: CallbackContext.DEFAULT_TYPE) -> bool:
|
||||
def remove_job_if_exists(name: str, context: ContextTypes.DEFAULT_TYPE) -> bool:
|
||||
"""Remove job with given name. Returns whether job was removed."""
|
||||
current_jobs = context.job_queue.get_jobs_by_name(name)
|
||||
if not current_jobs:
|
||||
@@ -56,29 +69,29 @@ def remove_job_if_exists(name: str, context: CallbackContext.DEFAULT_TYPE) -> bo
|
||||
return True
|
||||
|
||||
|
||||
async def set_timer(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
|
||||
async def set_timer(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Add a job to the queue."""
|
||||
chat_id = update.effective_message.chat_id
|
||||
try:
|
||||
# args[0] should contain the time for the timer in seconds
|
||||
due = int(context.args[0])
|
||||
due = float(context.args[0])
|
||||
if due < 0:
|
||||
await update.message.reply_text("Sorry we can not go back to future!")
|
||||
await update.effective_message.reply_text("Sorry we can not go back to future!")
|
||||
return
|
||||
|
||||
job_removed = remove_job_if_exists(str(chat_id), context)
|
||||
context.job_queue.run_once(alarm, due, chat_id=chat_id, name=str(chat_id), context=due)
|
||||
context.job_queue.run_once(alarm, due, chat_id=chat_id, name=str(chat_id), data=due)
|
||||
|
||||
text = "Timer successfully set!"
|
||||
if job_removed:
|
||||
text += " Old one was removed."
|
||||
await update.message.reply_text(text)
|
||||
await update.effective_message.reply_text(text)
|
||||
|
||||
except (IndexError, ValueError):
|
||||
await update.effective_message.reply_text("Usage: /set <seconds>")
|
||||
|
||||
|
||||
async def unset(update: Update, context: CallbackContext.DEFAULT_TYPE) -> None:
|
||||
async def unset(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Remove the job if the user changed their mind."""
|
||||
chat_id = update.message.chat_id
|
||||
job_removed = remove_job_if_exists(str(chat_id), context)
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
<!--
|
||||
Simple static Telegram WebApp. Does not verify the WebAppInitData, as a bot token would be needed for that.
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>python-telegram-bot Example WebApp</title>
|
||||
<script src="https://telegram.org/js/telegram-web-app.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/@jaames/iro@5"></script>
|
||||
</head>
|
||||
<script type="text/javascript">
|
||||
const colorPicker = new iro.ColorPicker('#picker', {
|
||||
borderColor: "#ffffff",
|
||||
borderWidth: 1,
|
||||
width: Math.round(document.documentElement.clientWidth / 2),
|
||||
});
|
||||
colorPicker.on('color:change', function (color) {
|
||||
document.body.style.background = color.hexString;
|
||||
});
|
||||
|
||||
Telegram.WebApp.ready();
|
||||
Telegram.WebApp.MainButton.setText('Choose Color').show().onClick(function () {
|
||||
const data = JSON.stringify({hex: colorPicker.color.hexString, rgb: colorPicker.color.rgb});
|
||||
Telegram.WebApp.sendData(data);
|
||||
Telegram.WebApp.close();
|
||||
});
|
||||
</script>
|
||||
<body style="background-color: #ffffff">
|
||||
<div style="position: absolute; margin-top: 5vh; margin-left: 5vw; height: 90vh; width: 90vw; border-radius: 5vh; background-color: var(--tg-theme-bg-color); box-shadow: 0 0 2vw
|
||||
#000000;">
|
||||
<div id="picker"
|
||||
style="display: flex; justify-content: center; align-items: center; height: 100%; width: 100%"></div>
|
||||
</div>
|
||||
</body>
|
||||
<script type="text/javascript">
|
||||
Telegram.WebApp.expand();
|
||||
</script>
|
||||
</html>
|
||||
@@ -0,0 +1,77 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable=unused-argument,wrong-import-position
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
|
||||
"""
|
||||
Simple example of a Telegram WebApp which displays a color picker.
|
||||
The static website for this website is hosted by the PTB team for your convenience.
|
||||
Currently only showcases starting the WebApp via a KeyboardButton, as all other methods would
|
||||
require a bot token.
|
||||
"""
|
||||
import json
|
||||
import logging
|
||||
|
||||
from telegram import __version__ as TG_VER
|
||||
|
||||
try:
|
||||
from telegram import __version_info__
|
||||
except ImportError:
|
||||
__version_info__ = (0, 0, 0, 0, 0) # type: ignore[assignment]
|
||||
|
||||
if __version_info__ < (20, 0, 0, "alpha", 1):
|
||||
raise RuntimeError(
|
||||
f"This example is not compatible with your current PTB version {TG_VER}. To view the "
|
||||
f"{TG_VER} version of this example, "
|
||||
f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html"
|
||||
)
|
||||
from telegram import KeyboardButton, ReplyKeyboardMarkup, ReplyKeyboardRemove, Update, WebAppInfo
|
||||
from telegram.ext import Application, CommandHandler, ContextTypes, MessageHandler, filters
|
||||
|
||||
# Enable logging
|
||||
logging.basicConfig(
|
||||
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", level=logging.INFO
|
||||
)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# Define a `/start` command handler.
|
||||
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Send a message with a button that opens a the web app."""
|
||||
await update.message.reply_text(
|
||||
"Please press the button below to choose a color via the WebApp.",
|
||||
reply_markup=ReplyKeyboardMarkup.from_button(
|
||||
KeyboardButton(
|
||||
text="Open the color picker!",
|
||||
web_app=WebAppInfo(url="https://python-telegram-bot.org/static/webappbot"),
|
||||
)
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
# Handle incoming WebAppData
|
||||
async def web_app_data(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Print the received data and remove the button."""
|
||||
# Here we use `json.loads`, since the WebApp sends the data JSON serialized string
|
||||
# (see webappbot.html)
|
||||
data = json.loads(update.effective_message.web_app_data.data)
|
||||
await update.message.reply_html(
|
||||
text=f"You selected the color with the HEX value <code>{data['hex']}</code>. The "
|
||||
f"corresponding RGB value is <code>{tuple(data['rgb'].values())}</code>.",
|
||||
reply_markup=ReplyKeyboardRemove(),
|
||||
)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
"""Start the bot."""
|
||||
# Create the Application and pass it your bot's token.
|
||||
application = Application.builder().token("TOKEN").build()
|
||||
|
||||
application.add_handler(CommandHandler("start", start))
|
||||
application.add_handler(MessageHandler(filters.StatusUpdate.WEB_APP_DATA, web_app_data))
|
||||
|
||||
# Run the bot until the user presses Ctrl-C
|
||||
application.run_polling()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -5,13 +5,14 @@ pre-commit
|
||||
# Make sure that the versions specified here match the pre-commit settings!
|
||||
black==22.3.0
|
||||
flake8==4.0.1
|
||||
pylint==2.13.8
|
||||
mypy==0.950
|
||||
pyupgrade==2.32.0
|
||||
pylint==2.13.9
|
||||
mypy==0.961
|
||||
pyupgrade==2.34.0
|
||||
isort==5.10.1
|
||||
|
||||
pytest==7.1.2
|
||||
pytest-asyncio==0.18.3
|
||||
pytest-timeout==2.1.0 # used to timeout tests
|
||||
|
||||
flaky # Used for flaky tests (flaky decorator)
|
||||
beautifulsoup4 # used in test_official for parsing tg docs
|
||||
|
||||
+2
-2
@@ -6,7 +6,7 @@
|
||||
# versions and only increase the lower bound if necessary
|
||||
|
||||
# httpx has no stable release yet, so let's be cautious for now
|
||||
httpx ~= 0.22.0
|
||||
httpx ~= 0.23.0
|
||||
# only telegram.ext: # Keep this line here; used in setup(-raw).py
|
||||
|
||||
# tornado is rather stable, but let's not allow the next mayor release without prior testing
|
||||
@@ -14,7 +14,7 @@ tornado~=6.1
|
||||
|
||||
# Cachetools and APS don't have a strict stability policy.
|
||||
# Let's be cautious for now.
|
||||
cachetools~=5.0.0
|
||||
cachetools~=5.2.0
|
||||
APScheduler~=3.9.1
|
||||
|
||||
# pytz is required by APS and just needs the lower bound due to #2120
|
||||
|
||||
@@ -61,9 +61,6 @@ disallow_incomplete_defs = True
|
||||
disallow_untyped_decorators = True
|
||||
show_error_codes = True
|
||||
|
||||
[mypy-telegram.vendor.*]
|
||||
ignore_errors = True
|
||||
|
||||
# For some files, it's easier to just disable strict-optional all together instead of
|
||||
# cluttering the code with `# type: ignore`s or stuff like
|
||||
# `if self.text is None: raise RuntimeError()`
|
||||
@@ -76,3 +73,10 @@ warn_unused_ignores = False
|
||||
|
||||
[mypy-apscheduler.*]
|
||||
ignore_missing_imports = True
|
||||
|
||||
# uvicorn and starlette are only used for the `customwebhookbot.py` example
|
||||
# let's just ignore type checking for them for now
|
||||
[mypy-uvicorn.*]
|
||||
ignore_missing_imports = True
|
||||
[mypy-starlette.*]
|
||||
ignore_missing_imports = True
|
||||
|
||||
@@ -42,10 +42,9 @@ def get_setup_kwargs(raw=False):
|
||||
raw_ext = "-raw" if raw else ""
|
||||
readme = Path(f'README{"_RAW" if raw else ""}.rst')
|
||||
|
||||
with Path("telegram/_version.py").open() as fh:
|
||||
for line in fh.readlines():
|
||||
if line.startswith("__version__"):
|
||||
exec(line)
|
||||
version_file = Path("telegram/_version.py").read_text()
|
||||
first_part = version_file.split("# SETUP.PY MARKER")[0]
|
||||
exec(first_part)
|
||||
|
||||
kwargs = dict(
|
||||
script_name=f"setup{raw_ext}.py",
|
||||
@@ -57,11 +56,11 @@ def get_setup_kwargs(raw=False):
|
||||
url="https://python-telegram-bot.org/",
|
||||
# Keywords supported by PyPI can be found at https://github.com/pypa/warehouse/blob/aafc5185e57e67d43487ce4faa95913dd4573e14/warehouse/templates/packaging/detail.html#L20-L58
|
||||
project_urls={
|
||||
"Documentation": "https://python-telegram-bot.readthedocs.io",
|
||||
"Documentation": "https://docs.python-telegram-bot.org",
|
||||
"Bug Tracker": "https://github.com/python-telegram-bot/python-telegram-bot/issues",
|
||||
"Source Code": "https://github.com/python-telegram-bot/python-telegram-bot",
|
||||
"News": "https://t.me/pythontelegrambotchannel",
|
||||
"Changelog": "https://python-telegram-bot.readthedocs.io/en/stable/changelog.html",
|
||||
"Changelog": "https://docs.python-telegram-bot.org/en/stable/changelog.html",
|
||||
},
|
||||
download_url=f"https://pypi.org/project/python-telegram-bot{raw_ext}/",
|
||||
keywords="python telegram bot api wrapper",
|
||||
@@ -72,9 +71,6 @@ def get_setup_kwargs(raw=False):
|
||||
install_requires=requirements,
|
||||
extras_require={
|
||||
"socks": "httpx[socks]",
|
||||
# json and cryptography are very stable, so we use a reasonably new version as
|
||||
# lower bound and have no upper bound
|
||||
"json": "ujson>=4.0.0",
|
||||
# 3.4-3.4.3 contained some cyclical import bugs
|
||||
"passport": "cryptography!=3.4,!=3.4.1,!=3.4.2,!=3.4.3,>=3.0",
|
||||
},
|
||||
|
||||
+29
-2
@@ -21,10 +21,13 @@
|
||||
__author__ = "devs@python-telegram-bot.org"
|
||||
|
||||
__all__ = ( # Keep this alphabetically ordered
|
||||
"__bot_api_version__",
|
||||
"__bot_api_version_info__",
|
||||
"__version__",
|
||||
"__version_info__",
|
||||
"Animation",
|
||||
"Audio",
|
||||
"Bot",
|
||||
"bot_api_version",
|
||||
"BotCommand",
|
||||
"BotCommandScope",
|
||||
"BotCommandScopeAllChatAdministrators",
|
||||
@@ -172,6 +175,7 @@ __all__ = ( # Keep this alphabetically ordered
|
||||
)
|
||||
|
||||
|
||||
from . import _version
|
||||
from ._bot import Bot
|
||||
from ._botcommand import BotCommand
|
||||
from ._botcommandscope import (
|
||||
@@ -308,7 +312,30 @@ from ._telegramobject import TelegramObject
|
||||
from ._update import Update
|
||||
from ._user import User
|
||||
from ._userprofilephotos import UserProfilePhotos
|
||||
from ._version import __version__, bot_api_version # noqa: F401
|
||||
|
||||
#: :obj:`str`: The version of the `python-telegram-bot` library as string.
|
||||
#: To get detailed information about the version number, please use :data:`__version_info__`
|
||||
#: instead.
|
||||
__version__ = _version.__version__
|
||||
#: :class:`typing.NamedTuple`: A tuple containing the five components of the version number:
|
||||
#: `major`, `minor`, `micro`, `releaselevel`, and `serial`.
|
||||
#: All values except `releaselevel` are integers.
|
||||
#: The release level is ``'alpha'``, ``'beta'``, ``'candidate'``, or ``'final'``.
|
||||
#: The components can also be accessed by name, so ``__version_info__[0]`` is equivalent to
|
||||
#: ``__version_info__.major`` and so on.
|
||||
#:
|
||||
#: .. versionadded:: 20.0
|
||||
__version_info__ = _version.__version_info__
|
||||
#: :obj:`str`: Shortcut for :const:`telegram.constants.BOT_API_VERSION`.
|
||||
#:
|
||||
#: .. versionchanged:: 20.0
|
||||
#: This constant was previously named ``bot_api_version``.
|
||||
__bot_api_version__ = _version.__bot_api_version__
|
||||
#: :class:`typing.NamedTuple`: Shortcut for :const:`telegram.constants.BOT_API_VERSION_INFO`.
|
||||
#:
|
||||
#: .. versionadded:: 20.0
|
||||
__bot_api_version_info__ = _version.__bot_api_version_info__
|
||||
|
||||
from ._videochat import (
|
||||
VideoChatEnded,
|
||||
VideoChatParticipantsInvited,
|
||||
|
||||
+765
-359
File diff suppressed because it is too large
Load Diff
@@ -260,5 +260,5 @@ class BotCommandScopeChatMember(BotCommandScope):
|
||||
self.chat_id = (
|
||||
chat_id if isinstance(chat_id, str) and chat_id.startswith("@") else int(chat_id)
|
||||
)
|
||||
self.user_id = int(user_id)
|
||||
self.user_id = user_id
|
||||
self._id_attrs = (self.type, self.chat_id, self.user_id)
|
||||
|
||||
+65
-59
@@ -65,7 +65,6 @@ class CallbackQuery(TelegramObject):
|
||||
|
||||
.. versionadded:: 13.6
|
||||
|
||||
|
||||
Args:
|
||||
id (:obj:`str`): Unique identifier for this query.
|
||||
from_user (:class:`telegram.User`): Sender.
|
||||
@@ -74,8 +73,8 @@ class CallbackQuery(TelegramObject):
|
||||
message (:class:`telegram.Message`, optional): Message with the callback button that
|
||||
originated the query. Note that message content and message date will not be available
|
||||
if the message is too old.
|
||||
data (:obj:`str`, optional): Data associated with the callback button. Be aware that a bad
|
||||
client can send arbitrary data in this field.
|
||||
data (:obj:`str`, optional): Data associated with the callback button. Be aware that the
|
||||
message, which originated the query, can contain no callback buttons with this data.
|
||||
inline_message_id (:obj:`str`, optional): Identifier of the message sent via the bot in
|
||||
inline mode, that originated the query.
|
||||
game_short_name (:obj:`str`, optional): Short name of a Game to be returned, serves as
|
||||
@@ -90,6 +89,10 @@ class CallbackQuery(TelegramObject):
|
||||
message (:class:`telegram.Message`): Optional. Message with the callback button that
|
||||
originated the query.
|
||||
data (:obj:`str` | :obj:`object`): Optional. Data associated with the callback button.
|
||||
|
||||
Tip:
|
||||
The value here is the same as the value passed in
|
||||
:paramref:`telegram.InlineKeyboardButton.callback_data`.
|
||||
inline_message_id (:obj:`str`): Optional. Identifier of the message sent via the bot in
|
||||
inline mode, that originated the query.
|
||||
game_short_name (:obj:`str`): Optional. Short name of a Game to be returned.
|
||||
@@ -149,9 +152,10 @@ class CallbackQuery(TelegramObject):
|
||||
async def answer(
|
||||
self,
|
||||
text: str = None,
|
||||
show_alert: bool = False,
|
||||
show_alert: bool = None,
|
||||
url: str = None,
|
||||
cache_time: int = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
@@ -188,21 +192,23 @@ class CallbackQuery(TelegramObject):
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
disable_web_page_preview: ODVInput[bool] = DEFAULT_NONE,
|
||||
reply_markup: "InlineKeyboardMarkup" = None,
|
||||
entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = 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: JSONDict = None,
|
||||
entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None,
|
||||
) -> Union[Message, bool]:
|
||||
"""Shortcut for either::
|
||||
|
||||
update.callback_query.message.edit_text(text, *args, **kwargs)
|
||||
await update.callback_query.message.edit_text(*args, **kwargs)
|
||||
|
||||
or::
|
||||
|
||||
bot.edit_message_text(text, inline_message_id=update.callback_query.inline_message_id,
|
||||
*args, **kwargs)
|
||||
await bot.edit_message_text(
|
||||
inline_message_id=update.callback_query.inline_message_id, *args, **kwargs,
|
||||
)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.edit_message_text` and :meth:`telegram.Message.edit_text`.
|
||||
@@ -245,23 +251,24 @@ class CallbackQuery(TelegramObject):
|
||||
self,
|
||||
caption: str = None,
|
||||
reply_markup: "InlineKeyboardMarkup" = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = 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,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
caption_entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None,
|
||||
) -> Union[Message, bool]:
|
||||
"""Shortcut for either::
|
||||
|
||||
update.callback_query.message.edit_caption(caption, *args, **kwargs)
|
||||
await update.callback_query.message.edit_caption(*args, **kwargs)
|
||||
|
||||
or::
|
||||
|
||||
bot.edit_message_caption(caption=caption
|
||||
inline_message_id=update.callback_query.inline_message_id,
|
||||
*args, **kwargs)
|
||||
await bot.edit_message_caption(
|
||||
inline_message_id=update.callback_query.inline_message_id, *args, **kwargs,
|
||||
)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.edit_message_caption` and :meth:`telegram.Message.edit_caption`.
|
||||
@@ -301,6 +308,7 @@ class CallbackQuery(TelegramObject):
|
||||
async def edit_message_reply_markup(
|
||||
self,
|
||||
reply_markup: Optional["InlineKeyboardMarkup"] = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
@@ -309,19 +317,12 @@ class CallbackQuery(TelegramObject):
|
||||
) -> Union[Message, bool]:
|
||||
"""Shortcut for either::
|
||||
|
||||
update.callback_query.message.edit_reply_markup(
|
||||
reply_markup=reply_markup,
|
||||
*args,
|
||||
**kwargs
|
||||
)
|
||||
await update.callback_query.message.edit_reply_markup(*args, **kwargs)
|
||||
|
||||
or::
|
||||
|
||||
bot.edit_message_reply_markup
|
||||
inline_message_id=update.callback_query.inline_message_id,
|
||||
reply_markup=reply_markup,
|
||||
*args,
|
||||
**kwargs
|
||||
await bot.edit_message_reply_markup(
|
||||
inline_message_id=update.callback_query.inline_message_id, *args, **kwargs
|
||||
)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
@@ -358,6 +359,7 @@ class CallbackQuery(TelegramObject):
|
||||
self,
|
||||
media: "InputMedia",
|
||||
reply_markup: "InlineKeyboardMarkup" = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
@@ -366,12 +368,13 @@ class CallbackQuery(TelegramObject):
|
||||
) -> Union[Message, bool]:
|
||||
"""Shortcut for either::
|
||||
|
||||
update.callback_query.message.edit_media(*args, **kwargs)
|
||||
await update.callback_query.message.edit_media(*args, **kwargs)
|
||||
|
||||
or::
|
||||
|
||||
bot.edit_message_media(inline_message_id=update.callback_query.inline_message_id,
|
||||
*args, **kwargs)
|
||||
await bot.edit_message_media(
|
||||
inline_message_id=update.callback_query.inline_message_id, *args, **kwargs
|
||||
)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.edit_message_media` and :meth:`telegram.Message.edit_media`.
|
||||
@@ -408,26 +411,26 @@ class CallbackQuery(TelegramObject):
|
||||
self,
|
||||
latitude: float = None,
|
||||
longitude: float = None,
|
||||
location: Location = None,
|
||||
reply_markup: "InlineKeyboardMarkup" = None,
|
||||
horizontal_accuracy: float = None,
|
||||
heading: int = None,
|
||||
proximity_alert_radius: int = None,
|
||||
*,
|
||||
location: Location = 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: JSONDict = None,
|
||||
horizontal_accuracy: float = None,
|
||||
heading: int = None,
|
||||
proximity_alert_radius: int = None,
|
||||
) -> Union[Message, bool]:
|
||||
"""Shortcut for either::
|
||||
|
||||
update.callback_query.message.edit_live_location(*args, **kwargs)
|
||||
await update.callback_query.message.edit_live_location(*args, **kwargs)
|
||||
|
||||
or::
|
||||
|
||||
bot.edit_message_live_location(
|
||||
inline_message_id=update.callback_query.inline_message_id,
|
||||
*args, **kwargs
|
||||
await bot.edit_message_live_location(
|
||||
inline_message_id=update.callback_query.inline_message_id, *args, **kwargs
|
||||
)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
@@ -475,6 +478,7 @@ class CallbackQuery(TelegramObject):
|
||||
async def stop_message_live_location(
|
||||
self,
|
||||
reply_markup: "InlineKeyboardMarkup" = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
@@ -483,13 +487,12 @@ class CallbackQuery(TelegramObject):
|
||||
) -> Union[Message, bool]:
|
||||
"""Shortcut for either::
|
||||
|
||||
update.callback_query.message.stop_live_location(*args, **kwargs)
|
||||
await update.callback_query.message.stop_live_location(*args, **kwargs)
|
||||
|
||||
or::
|
||||
|
||||
bot.stop_message_live_location(
|
||||
inline_message_id=update.callback_query.inline_message_id,
|
||||
*args, **kwargs
|
||||
await bot.stop_message_live_location(
|
||||
inline_message_id=update.callback_query.inline_message_id, *args, **kwargs
|
||||
)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
@@ -528,6 +531,7 @@ class CallbackQuery(TelegramObject):
|
||||
score: int,
|
||||
force: bool = None,
|
||||
disable_edit_message: bool = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
@@ -536,12 +540,13 @@ class CallbackQuery(TelegramObject):
|
||||
) -> Union[Message, bool]:
|
||||
"""Shortcut for either::
|
||||
|
||||
update.callback_query.message.set_game_score(*args, **kwargs)
|
||||
await update.callback_query.message.set_game_score(*args, **kwargs)
|
||||
|
||||
or::
|
||||
|
||||
bot.set_game_score(inline_message_id=update.callback_query.inline_message_id,
|
||||
*args, **kwargs)
|
||||
await bot.set_game_score(
|
||||
inline_message_id=update.callback_query.inline_message_id, *args, **kwargs
|
||||
)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.set_game_score` and :meth:`telegram.Message.set_game_score`.
|
||||
@@ -581,6 +586,7 @@ class CallbackQuery(TelegramObject):
|
||||
async def get_game_high_scores(
|
||||
self,
|
||||
user_id: Union[int, str],
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
@@ -589,12 +595,13 @@ class CallbackQuery(TelegramObject):
|
||||
) -> List["GameHighScore"]:
|
||||
"""Shortcut for either::
|
||||
|
||||
update.callback_query.message.get_game_high_score(*args, **kwargs)
|
||||
await update.callback_query.message.get_game_high_score(*args, **kwargs)
|
||||
|
||||
or::
|
||||
|
||||
bot.get_game_high_scores(inline_message_id=update.callback_query.inline_message_id,
|
||||
*args, **kwargs)
|
||||
await bot.get_game_high_scores(
|
||||
inline_message_id=update.callback_query.inline_message_id, *args, **kwargs
|
||||
)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Bot.get_game_high_scores` and
|
||||
@@ -627,6 +634,7 @@ class CallbackQuery(TelegramObject):
|
||||
|
||||
async def delete_message(
|
||||
self,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
@@ -635,10 +643,9 @@ class CallbackQuery(TelegramObject):
|
||||
) -> bool:
|
||||
"""Shortcut for::
|
||||
|
||||
update.callback_query.message.delete(*args, **kwargs)
|
||||
await update.callback_query.message.delete(*args, **kwargs)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Message.delete`.
|
||||
For the documentation of the arguments, please see :meth:`telegram.Message.delete`.
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
@@ -655,6 +662,7 @@ class CallbackQuery(TelegramObject):
|
||||
async def pin_message(
|
||||
self,
|
||||
disable_notification: ODVInput[bool] = DEFAULT_NONE,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
@@ -663,10 +671,9 @@ class CallbackQuery(TelegramObject):
|
||||
) -> bool:
|
||||
"""Shortcut for::
|
||||
|
||||
update.callback_query.message.pin(*args, **kwargs)
|
||||
await update.callback_query.message.pin(*args, **kwargs)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Message.pin`.
|
||||
For the documentation of the arguments, please see :meth:`telegram.Message.pin`.
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
@@ -683,6 +690,7 @@ class CallbackQuery(TelegramObject):
|
||||
|
||||
async def unpin_message(
|
||||
self,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
@@ -691,10 +699,9 @@ class CallbackQuery(TelegramObject):
|
||||
) -> bool:
|
||||
"""Shortcut for::
|
||||
|
||||
update.callback_query.message.unpin(*args, **kwargs)
|
||||
await update.callback_query.message.unpin(*args, **kwargs)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Message.unpin`.
|
||||
For the documentation of the arguments, please see :meth:`telegram.Message.unpin`.
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: On success, :obj:`True` is returned.
|
||||
@@ -718,25 +725,24 @@ class CallbackQuery(TelegramObject):
|
||||
reply_to_message_id: int = None,
|
||||
allow_sending_without_reply: DVInput[bool] = DEFAULT_NONE,
|
||||
reply_markup: ReplyMarkup = None,
|
||||
protect_content: ODVInput[bool] = DEFAULT_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: JSONDict = None,
|
||||
protect_content: ODVInput[bool] = DEFAULT_NONE,
|
||||
) -> "MessageId":
|
||||
"""Shortcut for::
|
||||
|
||||
update.callback_query.message.copy(
|
||||
chat_id,
|
||||
await update.callback_query.message.copy(
|
||||
from_chat_id=update.message.chat_id,
|
||||
message_id=update.message.message_id,
|
||||
*args,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
For the documentation of the arguments, please see
|
||||
:meth:`telegram.Message.copy`.
|
||||
For the documentation of the arguments, please see :meth:`telegram.Message.copy`.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.MessageId`: On success, returns the MessageId of the sent message.
|
||||
|
||||
+401
-108
File diff suppressed because it is too large
Load Diff
@@ -124,7 +124,7 @@ class ChatInviteLink(TelegramObject):
|
||||
|
||||
# Optionals
|
||||
self.expire_date = expire_date
|
||||
self.member_limit = int(member_limit) if member_limit is not None else None
|
||||
self.member_limit = member_limit
|
||||
self.name = name
|
||||
self.pending_join_request_count = (
|
||||
int(pending_join_request_count) if pending_join_request_count is not None else None
|
||||
|
||||
@@ -114,6 +114,7 @@ class ChatJoinRequest(TelegramObject):
|
||||
|
||||
async def approve(
|
||||
self,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
@@ -145,6 +146,7 @@ class ChatJoinRequest(TelegramObject):
|
||||
|
||||
async def decline(
|
||||
self,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
|
||||
@@ -45,6 +45,7 @@ class ChatMember(TelegramObject):
|
||||
considered equal, if their :attr:`user` and :attr:`status` are equal.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
* As of Bot API 5.3, :class:`ChatMember` is nothing but the base class for the subclasses
|
||||
listed above and is no longer returned directly by :meth:`~telegram.Bot.get_chat`.
|
||||
Therefore, most of the arguments and attributes were removed and you should no longer
|
||||
|
||||
@@ -166,7 +166,7 @@ class ChatMemberUpdated(TelegramObject):
|
||||
|
||||
Returns:
|
||||
Dict[:obj:`str`, Tuple[:class:`object`, :class:`object`]]: A dictionary mapping
|
||||
attribute names to tuples of the form ``(old_value, new_value)``
|
||||
attribute names to tuples of the form ``(old_value, new_value)``
|
||||
"""
|
||||
# we first get the names of the attributes that have changed
|
||||
# user.to_dict() is unhashable, so that needs some special casing further down
|
||||
|
||||
@@ -67,6 +67,7 @@ class _BaseMedium(TelegramObject):
|
||||
|
||||
async def get_file(
|
||||
self,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
|
||||
@@ -88,8 +88,8 @@ class Animation(_BaseThumbedMedium):
|
||||
bot=bot,
|
||||
)
|
||||
# Required
|
||||
self.width = int(width)
|
||||
self.height = int(height)
|
||||
self.width = width
|
||||
self.height = height
|
||||
self.duration = duration
|
||||
# Optional
|
||||
self.mime_type = mime_type
|
||||
|
||||
@@ -95,6 +95,7 @@ class ChatPhoto(TelegramObject):
|
||||
|
||||
async def get_small_file(
|
||||
self,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
@@ -124,6 +125,7 @@ class ChatPhoto(TelegramObject):
|
||||
|
||||
async def get_big_file(
|
||||
self,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram InputFile."""
|
||||
|
||||
import imghdr
|
||||
import logging
|
||||
import mimetypes
|
||||
from pathlib import Path
|
||||
@@ -35,7 +34,11 @@ class InputFile:
|
||||
"""This object represents a Telegram InputFile.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
The former attribute ``attach`` was renamed to :attr:`attach_name`.
|
||||
|
||||
* The former attribute ``attach`` was renamed to :attr:`attach_name`.
|
||||
* Method ``is_image`` was removed. If you pass :obj:`bytes` to :paramref:`obj` and would
|
||||
like to have the mime type automatically guessed, please pass :paramref:`filename`
|
||||
in addition.
|
||||
|
||||
Args:
|
||||
obj (:term:`file object` | :obj:`bytes` | :obj:`str`): An open file descriptor or the files
|
||||
@@ -82,39 +85,13 @@ class InputFile:
|
||||
):
|
||||
filename = Path(obj.name).name # type: ignore[union-attr]
|
||||
|
||||
image_mime_type = self.is_image(self.input_file_content)
|
||||
if image_mime_type:
|
||||
self.mimetype = image_mime_type
|
||||
elif filename:
|
||||
self.mimetype = mimetypes.guess_type(filename)[0] or _DEFAULT_MIME_TYPE
|
||||
if filename:
|
||||
self.mimetype = mimetypes.guess_type(filename, strict=False)[0] or _DEFAULT_MIME_TYPE
|
||||
else:
|
||||
self.mimetype = _DEFAULT_MIME_TYPE
|
||||
|
||||
self.filename = filename or self.mimetype.replace("/", ".")
|
||||
|
||||
@staticmethod
|
||||
def is_image(stream: bytes) -> Optional[str]:
|
||||
"""Check if the content file is an image by analyzing its headers.
|
||||
|
||||
Args:
|
||||
stream (:obj:`bytes`): A byte stream representing the content of a file.
|
||||
|
||||
Returns:
|
||||
:obj:`str` | :obj:`None`: The mime-type of an image, if the input is an image, or
|
||||
:obj:`None` else.
|
||||
|
||||
"""
|
||||
try:
|
||||
image = imghdr.what(None, stream)
|
||||
if image:
|
||||
return f"image/{image}"
|
||||
return None
|
||||
except Exception:
|
||||
logger.debug(
|
||||
"Could not parse file content. Assuming that file is not an image.", exc_info=True
|
||||
)
|
||||
return None
|
||||
|
||||
@property
|
||||
def field_tuple(self) -> FieldTuple:
|
||||
"""Field tuple representing the contents of the file for upload to the Telegram servers.
|
||||
|
||||
@@ -76,13 +76,13 @@ class Location(TelegramObject):
|
||||
**_kwargs: Any,
|
||||
):
|
||||
# Required
|
||||
self.longitude = float(longitude)
|
||||
self.latitude = float(latitude)
|
||||
self.longitude = longitude
|
||||
self.latitude = latitude
|
||||
|
||||
# Optionals
|
||||
self.horizontal_accuracy = float(horizontal_accuracy) if horizontal_accuracy else None
|
||||
self.live_period = int(live_period) if live_period else None
|
||||
self.heading = int(heading) if heading else None
|
||||
self.horizontal_accuracy = horizontal_accuracy
|
||||
self.live_period = live_period
|
||||
self.heading = heading
|
||||
self.proximity_alert_radius = (
|
||||
int(proximity_alert_radius) if proximity_alert_radius else None
|
||||
)
|
||||
|
||||
@@ -72,5 +72,5 @@ class PhotoSize(_BaseMedium):
|
||||
file_id=file_id, file_unique_id=file_unique_id, file_size=file_size, bot=bot
|
||||
)
|
||||
# Required
|
||||
self.width = int(width)
|
||||
self.height = int(height)
|
||||
self.width = width
|
||||
self.height = height
|
||||
|
||||
@@ -22,6 +22,7 @@ from typing import TYPE_CHECKING, Any, ClassVar, List, Optional
|
||||
|
||||
from telegram import constants
|
||||
from telegram._files._basethumbedmedium import _BaseThumbedMedium
|
||||
from telegram._files.file import File
|
||||
from telegram._files.photosize import PhotoSize
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._utils.types import JSONDict
|
||||
@@ -62,6 +63,10 @@ class Sticker(_BaseThumbedMedium):
|
||||
position where the mask should be placed.
|
||||
file_size (:obj:`int`, optional): File size in bytes.
|
||||
bot (:class:`telegram.Bot`, optional): The Bot to use for instance methods.
|
||||
premium_animation (:class:`telegram.File`, optional): Premium animation for the sticker,
|
||||
if the sticker is premium.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
_kwargs (:obj:`dict`): Arbitrary keyword arguments.
|
||||
|
||||
Attributes:
|
||||
@@ -83,6 +88,10 @@ class Sticker(_BaseThumbedMedium):
|
||||
where the mask should be placed.
|
||||
file_size (:obj:`int`): Optional. File size in bytes.
|
||||
bot (:class:`telegram.Bot`): Optional. The Bot to use for instance methods.
|
||||
premium_animation (:class:`telegram.File`): Optional. Premium animation for the
|
||||
sticker, if the sticker is premium.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
|
||||
"""
|
||||
|
||||
@@ -94,6 +103,7 @@ class Sticker(_BaseThumbedMedium):
|
||||
"mask_position",
|
||||
"set_name",
|
||||
"width",
|
||||
"premium_animation",
|
||||
)
|
||||
|
||||
def __init__(
|
||||
@@ -110,6 +120,7 @@ class Sticker(_BaseThumbedMedium):
|
||||
set_name: str = None,
|
||||
mask_position: "MaskPosition" = None,
|
||||
bot: "Bot" = None,
|
||||
premium_animation: "File" = None,
|
||||
**_kwargs: Any,
|
||||
):
|
||||
super().__init__(
|
||||
@@ -120,14 +131,15 @@ class Sticker(_BaseThumbedMedium):
|
||||
bot=bot,
|
||||
)
|
||||
# Required
|
||||
self.width = int(width)
|
||||
self.height = int(height)
|
||||
self.width = width
|
||||
self.height = height
|
||||
self.is_animated = is_animated
|
||||
self.is_video = is_video
|
||||
# Optional
|
||||
self.emoji = emoji
|
||||
self.set_name = set_name
|
||||
self.mask_position = mask_position
|
||||
self.premium_animation = premium_animation
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["Sticker"]:
|
||||
@@ -139,6 +151,7 @@ class Sticker(_BaseThumbedMedium):
|
||||
|
||||
data["thumb"] = PhotoSize.de_json(data.get("thumb"), bot)
|
||||
data["mask_position"] = MaskPosition.de_json(data.get("mask_position"), bot)
|
||||
data["premium_animation"] = File.de_json(data.get("premium_animation"), bot)
|
||||
|
||||
return cls(bot=bot, **data)
|
||||
|
||||
|
||||
@@ -47,7 +47,8 @@ class Venue(TelegramObject):
|
||||
"arts_entertainment/default", "arts_entertainment/aquarium" or "food/icecream".)
|
||||
google_place_id (:obj:`str`, optional): Google Places identifier of the venue.
|
||||
google_place_type (:obj:`str`, optional): Google Places type of the venue. (See
|
||||
`supported types <https://developers.google.com/places/web-service/supported_types>`_.)
|
||||
`supported types <https://developers.google.com/maps/documentation/places/web-service\
|
||||
/supported_types>`_.)
|
||||
**kwargs (:obj:`dict`): Arbitrary keyword arguments.
|
||||
|
||||
Attributes:
|
||||
|
||||
@@ -89,8 +89,8 @@ class Video(_BaseThumbedMedium):
|
||||
bot=bot,
|
||||
)
|
||||
# Required
|
||||
self.width = int(width)
|
||||
self.height = int(height)
|
||||
self.width = width
|
||||
self.height = height
|
||||
self.duration = duration
|
||||
# Optional
|
||||
self.mime_type = mime_type
|
||||
|
||||
@@ -81,5 +81,5 @@ class VideoNote(_BaseThumbedMedium):
|
||||
bot=bot,
|
||||
)
|
||||
# Required
|
||||
self.length = int(length)
|
||||
self.length = length
|
||||
self.duration = duration
|
||||
|
||||
@@ -75,6 +75,6 @@ class Voice(_BaseMedium):
|
||||
bot=bot,
|
||||
)
|
||||
# Required
|
||||
self.duration = int(duration)
|
||||
self.duration = duration
|
||||
# Optional
|
||||
self.mime_type = mime_type
|
||||
|
||||
@@ -68,12 +68,12 @@ class ForceReply(TelegramObject):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
selective: bool = False,
|
||||
selective: bool = None,
|
||||
input_field_placeholder: str = None,
|
||||
**_kwargs: Any,
|
||||
):
|
||||
self.force_reply = True
|
||||
self.selective = bool(selective)
|
||||
self.selective = selective
|
||||
self.input_field_placeholder = input_field_placeholder
|
||||
|
||||
self._id_attrs = (self.selective,)
|
||||
|
||||
@@ -63,8 +63,9 @@ class Game(TelegramObject):
|
||||
game message. Can be automatically edited to include current high scores for the game
|
||||
when the bot calls :meth:`telegram.Bot.set_game_score`, or manually edited
|
||||
using :meth:`telegram.Bot.edit_message_text`.
|
||||
text_entities (List[:class:`telegram.MessageEntity`]): Optional. Special entities that
|
||||
text_entities (List[:class:`telegram.MessageEntity`]): Special entities that
|
||||
appear in text, such as usernames, URLs, bot commands, etc.
|
||||
This list is empty if the message does not contain text entities.
|
||||
animation (:class:`telegram.Animation`): Optional. Animation that will be displayed in the
|
||||
game message in chats. Upload via `BotFather <https://t.me/BotFather>`_.
|
||||
|
||||
@@ -182,7 +183,7 @@ class Game(TelegramObject):
|
||||
|
||||
return {
|
||||
entity: self.parse_text_entity(entity)
|
||||
for entity in (self.text_entities or [])
|
||||
for entity in self.text_entities
|
||||
if entity.type in types
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram InlineKeyboardButton."""
|
||||
|
||||
from typing import TYPE_CHECKING, Any, Optional
|
||||
from typing import TYPE_CHECKING, Any, Optional, Union
|
||||
|
||||
from telegram._games.callbackgame import CallbackGame
|
||||
from telegram._loginurl import LoginUrl
|
||||
@@ -35,8 +35,8 @@ class InlineKeyboardButton(TelegramObject):
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`text`, :attr:`url`, :attr:`login_url`, :attr:`callback_data`,
|
||||
:attr:`switch_inline_query`, :attr:`switch_inline_query_current_chat`, :attr:`callback_game`
|
||||
and :attr:`pay` are equal.
|
||||
:attr:`switch_inline_query`, :attr:`switch_inline_query_current_chat`, :attr:`callback_game`,
|
||||
:attr:`web_app` and :attr:`pay` are equal.
|
||||
|
||||
Note:
|
||||
* You must use exactly one of the optional fields. Mind that :attr:`callback_game` is not
|
||||
@@ -62,6 +62,10 @@ class InlineKeyboardButton(TelegramObject):
|
||||
|
||||
* After Bot API 6.1, only ``HTTPS`` links will be allowed in :paramref:`login_url`.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
:attr:`web_app` is considered as well when comparing objects of this type in terms of
|
||||
equality.
|
||||
|
||||
Args:
|
||||
text (:obj:`str`): Label text on the button.
|
||||
url (:obj:`str`, optional): HTTP or tg:// url to be opened when the button is pressed.
|
||||
@@ -78,6 +82,10 @@ class InlineKeyboardButton(TelegramObject):
|
||||
callback_data (:obj:`str` | :obj:`object`, optional): Data to be sent in a callback query
|
||||
to the bot when button is pressed, UTF-8 1-64 bytes. If the bot instance allows
|
||||
arbitrary callback data, anything can be passed.
|
||||
|
||||
Tip:
|
||||
The value entered here will be available in :attr:`telegram.CallbackQuery.data`.
|
||||
|
||||
web_app (:obj:`telegram.WebAppInfo`, optional): Description of the `Web App
|
||||
<https://core.telegram.org/bots/webapps>`_ that will be launched when the user presses
|
||||
the button. The Web App will be able to send an arbitrary message on behalf of the user
|
||||
@@ -155,7 +163,7 @@ class InlineKeyboardButton(TelegramObject):
|
||||
self,
|
||||
text: str,
|
||||
url: str = None,
|
||||
callback_data: object = None,
|
||||
callback_data: Union[str, object] = None,
|
||||
switch_inline_query: str = None,
|
||||
switch_inline_query_current_chat: str = None,
|
||||
callback_game: CallbackGame = None,
|
||||
@@ -185,6 +193,7 @@ class InlineKeyboardButton(TelegramObject):
|
||||
self.url,
|
||||
self.login_url,
|
||||
self.callback_data,
|
||||
self.web_app,
|
||||
self.switch_inline_query,
|
||||
self.switch_inline_query_current_chat,
|
||||
self.callback_game,
|
||||
@@ -205,7 +214,7 @@ class InlineKeyboardButton(TelegramObject):
|
||||
|
||||
return cls(**data)
|
||||
|
||||
def update_callback_data(self, callback_data: object) -> None:
|
||||
def update_callback_data(self, callback_data: Union[str, object]) -> None:
|
||||
"""
|
||||
Sets :attr:`callback_data` to the passed object. Intended to be used by
|
||||
:class:`telegram.ext.CallbackDataCache`.
|
||||
|
||||
@@ -43,6 +43,13 @@ class InlineQuery(TelegramObject):
|
||||
Note:
|
||||
In Python :keyword:`from` is a reserved word use :paramref:`from_user` instead.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
* The following are now keyword-only arguments in Bot methods:
|
||||
``{read, write, connect, pool}_timeout``, :paramref:`answer.api_kwargs`,
|
||||
``auto_pagination``. Use a named argument for those,
|
||||
and notice that some positional arguments changed position as a result.
|
||||
|
||||
Args:
|
||||
id (:obj:`str`): Unique identifier for this query.
|
||||
from_user (:class:`telegram.User`): Sender.
|
||||
@@ -118,18 +125,19 @@ class InlineQuery(TelegramObject):
|
||||
results: Union[
|
||||
Sequence["InlineQueryResult"], Callable[[int], Optional[Sequence["InlineQueryResult"]]]
|
||||
],
|
||||
cache_time: int = 300,
|
||||
cache_time: int = None,
|
||||
is_personal: bool = None,
|
||||
next_offset: str = None,
|
||||
switch_pm_text: str = None,
|
||||
switch_pm_parameter: str = None,
|
||||
*,
|
||||
current_offset: str = None,
|
||||
auto_pagination: bool = False,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
pool_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
current_offset: str = None,
|
||||
api_kwargs: JSONDict = None,
|
||||
auto_pagination: bool = False,
|
||||
) -> bool:
|
||||
"""Shortcut for::
|
||||
|
||||
@@ -146,7 +154,7 @@ class InlineQuery(TelegramObject):
|
||||
.. versionchanged:: 20.0
|
||||
Raises :class:`ValueError` instead of :class:`TypeError`.
|
||||
|
||||
Args:
|
||||
Keyword Args:
|
||||
auto_pagination (:obj:`bool`, optional): If set to :obj:`True`, :attr:`offset` will be
|
||||
passed as
|
||||
:paramref:`current_offset <telegram.Bot.answer_inline_query.current_offset>` to
|
||||
|
||||
@@ -116,8 +116,8 @@ class InlineQueryResultLocation(InlineQueryResult):
|
||||
):
|
||||
# Required
|
||||
super().__init__(InlineQueryResultType.LOCATION, id)
|
||||
self.latitude = float(latitude)
|
||||
self.longitude = float(longitude)
|
||||
self.latitude = latitude
|
||||
self.longitude = longitude
|
||||
self.title = title
|
||||
|
||||
# Optionals
|
||||
@@ -127,8 +127,8 @@ class InlineQueryResultLocation(InlineQueryResult):
|
||||
self.thumb_url = thumb_url
|
||||
self.thumb_width = thumb_width
|
||||
self.thumb_height = thumb_height
|
||||
self.horizontal_accuracy = float(horizontal_accuracy) if horizontal_accuracy else None
|
||||
self.heading = int(heading) if heading else None
|
||||
self.horizontal_accuracy = horizontal_accuracy
|
||||
self.heading = heading
|
||||
self.proximity_alert_radius = (
|
||||
int(proximity_alert_radius) if proximity_alert_radius else None
|
||||
)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user