mirror of
https://github.com/python-telegram-bot/python-telegram-bot.git
synced 2026-06-19 23:55:29 +00:00
Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 71530f404d | |||
| 0cd7ecab50 | |||
| c5f9e53d44 | |||
| acf1541395 | |||
| 906a1b8d7d | |||
| a2fddbe85c | |||
| 68e87db909 | |||
| a7bfb0c3a1 | |||
| e76ee6bb57 | |||
| 65061f8a99 | |||
| dabbbcafcb | |||
| 1eb4b40dbf | |||
| 7167936692 | |||
| aa3ca38837 | |||
| b22c3cc5c0 |
@@ -71,3 +71,6 @@ telegram.webp
|
||||
|
||||
# original files from merges
|
||||
*.orig
|
||||
|
||||
# Exclude .exrc file for Vim
|
||||
.exrc
|
||||
|
||||
@@ -13,12 +13,14 @@ The following wonderful people contributed directly or indirectly to this projec
|
||||
- `bimmlerd <https://github.com/bimmlerd>`_
|
||||
- `Eli Gao <https://github.com/eligao>`_
|
||||
- `ErgoZ Riftbit Vaper <https://github.com/ergoz>`_
|
||||
- `Eugene Lisitsky <https://github.com/lisitsky>`_
|
||||
- `franciscod <https://github.com/franciscod>`_
|
||||
- `Jacob Bom <https://github.com/bomjacob>`_
|
||||
- `JASON0916 <https://github.com/JASON0916>`_
|
||||
- `jh0ker <https://github.com/jh0ker>`_
|
||||
- `JRoot3D <https://github.com/JRoot3D>`_
|
||||
- `jlmadurga <https://github.com/jlmadurga>`_
|
||||
- `Kjwon15 <https://github.com/kjwon15>`_
|
||||
- `Li-aung Yip <https://github.com/LiaungYip>`_
|
||||
- `macrojames <https://github.com/macrojames>`_
|
||||
- `Michael Elovskikh <https://github.com/wronglink>`_
|
||||
@@ -32,6 +34,7 @@ The following wonderful people contributed directly or indirectly to this projec
|
||||
- `Shelomentsev D <https://github.com/shelomentsevd>`_
|
||||
- `sooyhwang <https://github.com/sooyhwang>`_
|
||||
- `Valentijn <https://github.com/Faalentijn>`_
|
||||
- `voider1 <https://github.com/voider1>`_
|
||||
- `wjt <https://github.com/wjt>`_
|
||||
|
||||
Please add yourself here alphabetically when you submit your first pull request.
|
||||
|
||||
+11
@@ -2,6 +2,17 @@
|
||||
Changes
|
||||
=======
|
||||
|
||||
**2016-12-11**
|
||||
|
||||
*Released 5.3*
|
||||
|
||||
- Implement API changes of November 21st (Bot API 2.3)
|
||||
- ``JobQueue`` now supports ``datetime.timedelta`` in addition to seconds
|
||||
- ``JobQueue`` now supports running jobs only on certain days
|
||||
- New ``Filters.reply`` filter
|
||||
- Bugfix for ``Message.edit_reply_markup``
|
||||
- Other bugfixes
|
||||
|
||||
**2016-10-25**
|
||||
|
||||
*Released 5.2*
|
||||
|
||||
+11
-8
@@ -59,9 +59,9 @@ author = u'Leandro Toledo'
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '5.2' # telegram.__version__[:3]
|
||||
version = '5.3' # telegram.__version__[:3]
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '5.2.0' # telegram.__version__
|
||||
release = '5.3.0' # telegram.__version__
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
@@ -131,7 +131,7 @@ html_theme = 'sphinx_rtd_theme'
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top
|
||||
# of the sidebar.
|
||||
#html_logo = None
|
||||
html_logo = 'ptb-logo-orange.png'
|
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
@@ -209,14 +209,17 @@ htmlhelp_basename = 'PythonTelegramBotdoc'
|
||||
# -- Options for LaTeX output ---------------------------------------------
|
||||
|
||||
latex_elements = {
|
||||
|
||||
# The paper size ('letterpaper' or 'a4paper').
|
||||
#'papersize': 'letterpaper',
|
||||
'papersize': 'a4paper',
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#'pointsize': '10pt',
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#'preamble': '',
|
||||
'preamble': r'''\setcounter{tocdepth}{2}
|
||||
\usepackage{enumitem}
|
||||
\setlistdepth{99}''',
|
||||
|
||||
# Latex figure (float) alignment
|
||||
#'figure_align': 'htbp',
|
||||
@@ -227,12 +230,12 @@ latex_elements = {
|
||||
# author, documentclass [howto, manual, or own class]).
|
||||
latex_documents = [
|
||||
(master_doc, 'PythonTelegramBot.tex', u'Python Telegram Bot Documentation',
|
||||
u'Leandro Toledo', 'manual'),
|
||||
author, 'manual'),
|
||||
]
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
# the title page.
|
||||
#latex_logo = None
|
||||
latex_logo = 'ptb-logo_1024.png'
|
||||
|
||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
||||
# not chapters.
|
||||
@@ -271,7 +274,7 @@ man_pages = [
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [
|
||||
(master_doc, 'PythonTelegramBot', u'Python Telegram Bot Documentation',
|
||||
author, 'PythonTelegramBot', 'Not just a Python wrapper around the Telegram Bot API',
|
||||
author, 'PythonTelegramBot', "We have made you a wrapper you can't refuse",
|
||||
'Miscellaneous'),
|
||||
]
|
||||
|
||||
|
||||
@@ -6,12 +6,8 @@
|
||||
Welcome to Python Telegram Bot's documentation!
|
||||
===============================================
|
||||
|
||||
Contents:
|
||||
telegram
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
telegram
|
||||
|
||||
|
||||
Indices and tables
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
telegram
|
||||
========
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 4
|
||||
|
||||
telegram
|
||||
Executable
BIN
Binary file not shown.
|
After Width: | Height: | Size: 74 KiB |
Executable
BIN
Binary file not shown.
|
After Width: | Height: | Size: 71 KiB |
@@ -0,0 +1,7 @@
|
||||
telegram.animation module
|
||||
=========================
|
||||
|
||||
.. automodule:: telegram.animation
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,7 @@
|
||||
telegram.callbackgame module
|
||||
============================
|
||||
|
||||
.. automodule:: telegram.callbackgame
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,7 @@
|
||||
telegram.callbackquery module
|
||||
=============================
|
||||
|
||||
.. automodule:: telegram.callbackquery
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,7 @@
|
||||
telegram.chatmember module
|
||||
==========================
|
||||
|
||||
.. automodule:: telegram.chatmember
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,17 @@
|
||||
telegram.contrib package
|
||||
========================
|
||||
|
||||
Submodules
|
||||
----------
|
||||
|
||||
.. toctree::
|
||||
|
||||
telegram.contrib.botan
|
||||
|
||||
Module contents
|
||||
---------------
|
||||
|
||||
.. automodule:: telegram.contrib
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
@@ -10,6 +10,7 @@ Submodules
|
||||
telegram.ext.dispatcher
|
||||
telegram.ext.jobqueue
|
||||
telegram.ext.handler
|
||||
telegram.ext.callbackqueryhandler
|
||||
telegram.ext.choseninlineresulthandler
|
||||
telegram.ext.conversationhandler
|
||||
telegram.ext.commandhandler
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
telegram.file module
|
||||
====================
|
||||
|
||||
.. automodule:: telegram.file
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,7 @@
|
||||
telegram.game module
|
||||
====================
|
||||
|
||||
.. automodule:: telegram.game
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,7 @@
|
||||
telegram.gamehighscore module
|
||||
=============================
|
||||
|
||||
.. automodule:: telegram.gamehighscore
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.inlinekeyboardbutton module
|
||||
===========================
|
||||
====================================
|
||||
|
||||
.. automodule:: telegram.inlinekeyboardbutton
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.inlinekeyboardmarkup module
|
||||
==========================
|
||||
====================================
|
||||
|
||||
.. automodule:: telegram.inlinekeyboardmarkup
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.inlinequeryresultarticle module
|
||||
=================================
|
||||
========================================
|
||||
|
||||
.. automodule:: telegram.inlinequeryresultarticle
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.inlinequeryresultaudio module
|
||||
=================================
|
||||
======================================
|
||||
|
||||
.. automodule:: telegram.inlinequeryresultaudio
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.inlinequeryresultcachedaudio module
|
||||
=================================
|
||||
============================================
|
||||
|
||||
.. automodule:: telegram.inlinequeryresultcachedaudio
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.inlinequeryresultcacheddocument module
|
||||
=================================
|
||||
===============================================
|
||||
|
||||
.. automodule:: telegram.inlinequeryresultcacheddocument
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.inlinequeryresultcachedgif module
|
||||
=================================
|
||||
==========================================
|
||||
|
||||
.. automodule:: telegram.inlinequeryresultcachedgif
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.inlinequeryresultcachedmpeg4gif module
|
||||
=================================
|
||||
===============================================
|
||||
|
||||
.. automodule:: telegram.inlinequeryresultcachedmpeg4gif
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.inlinequeryresultcachedphoto module
|
||||
=================================
|
||||
============================================
|
||||
|
||||
.. automodule:: telegram.inlinequeryresultcachedphoto
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.inlinequeryresultcachedsticker module
|
||||
=================================
|
||||
==============================================
|
||||
|
||||
.. automodule:: telegram.inlinequeryresultcachedsticker
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.inlinequeryresultcachedvideo module
|
||||
=================================
|
||||
============================================
|
||||
|
||||
.. automodule:: telegram.inlinequeryresultcachedvideo
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.inlinequeryresultcachedvoice module
|
||||
=================================
|
||||
============================================
|
||||
|
||||
.. automodule:: telegram.inlinequeryresultcachedvoice
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.inlinequeryresultcontact module
|
||||
=================================
|
||||
========================================
|
||||
|
||||
.. automodule:: telegram.inlinequeryresultcontact
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.inlinequeryresultdocument module
|
||||
=================================
|
||||
=========================================
|
||||
|
||||
.. automodule:: telegram.inlinequeryresultdocument
|
||||
:members:
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
telegram.inlinequeryresultgame module
|
||||
=====================================
|
||||
|
||||
.. automodule:: telegram.inlinequeryresultgame
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.inlinequeryresultgif module
|
||||
=================================
|
||||
====================================
|
||||
|
||||
.. automodule:: telegram.inlinequeryresultgif
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.inlinequeryresultlocation module
|
||||
=================================
|
||||
=========================================
|
||||
|
||||
.. automodule:: telegram.inlinequeryresultlocation
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.inlinequeryresultmpeg4gif module
|
||||
=================================
|
||||
=========================================
|
||||
|
||||
.. automodule:: telegram.inlinequeryresultmpeg4gif
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.inlinequeryresultphoto module
|
||||
=================================
|
||||
======================================
|
||||
|
||||
.. automodule:: telegram.inlinequeryresultphoto
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.inlinequeryresultvenue module
|
||||
=================================
|
||||
======================================
|
||||
|
||||
.. automodule:: telegram.inlinequeryresultvenue
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.inlinequeryresultvideo module
|
||||
=================================
|
||||
======================================
|
||||
|
||||
.. automodule:: telegram.inlinequeryresultvideo
|
||||
:members:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
telegram.inlinequeryresultvoice module
|
||||
=================================
|
||||
======================================
|
||||
|
||||
.. automodule:: telegram.inlinequeryresultvoice
|
||||
:members:
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
telegram.inputcontactmessagecontent module
|
||||
==========================================
|
||||
|
||||
.. automodule:: telegram.inputcontactmessagecontent
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,7 @@
|
||||
telegram.inputlocationmessagecontent module
|
||||
===========================================
|
||||
|
||||
.. automodule:: telegram.inputlocationmessagecontent
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,7 @@
|
||||
telegram.inputmessagecontent module
|
||||
===================================
|
||||
|
||||
.. automodule:: telegram.inputmessagecontent
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,7 @@
|
||||
telegram.inputtextmessagecontent module
|
||||
=======================================
|
||||
|
||||
.. automodule:: telegram.inputtextmessagecontent
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,7 @@
|
||||
telegram.inputvenuemessagecontent module
|
||||
========================================
|
||||
|
||||
.. automodule:: telegram.inputvenuemessagecontent
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,7 @@
|
||||
telegram.keyboardbutton module
|
||||
==============================
|
||||
|
||||
.. automodule:: telegram.keyboardbutton
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,7 @@
|
||||
telegram.messageentity module
|
||||
=============================
|
||||
|
||||
.. automodule:: telegram.messageentity
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,7 @@
|
||||
telegram.parsemode module
|
||||
=========================
|
||||
|
||||
.. automodule:: telegram.parsemode
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
@@ -1,7 +0,0 @@
|
||||
telegram.replykeyboardhide module
|
||||
=================================
|
||||
|
||||
.. automodule:: telegram.replykeyboardhide
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,7 @@
|
||||
telegram.replykeyboardremove module
|
||||
===================================
|
||||
|
||||
.. automodule:: telegram.replykeyboardremove
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
+31
-13
@@ -6,14 +6,30 @@ Submodules
|
||||
|
||||
.. toctree::
|
||||
|
||||
telegram.contrib
|
||||
telegram.ext
|
||||
telegram.animation
|
||||
telegram.audio
|
||||
telegram.base
|
||||
telegram.bot
|
||||
telegram.ext
|
||||
telegram.inlinequery
|
||||
telegram.inlinequeryresult
|
||||
telegram.callbackgame
|
||||
telegram.callbackquery
|
||||
telegram.chat
|
||||
telegram.chataction
|
||||
telegram.chatmember
|
||||
telegram.choseninlineresult
|
||||
telegram.constants
|
||||
telegram.contact
|
||||
telegram.document
|
||||
telegram.error
|
||||
telegram.file
|
||||
telegram.forcereply
|
||||
telegram.game
|
||||
telegram.gamehighscore
|
||||
telegram.inlinekeyboardbutton
|
||||
telegram.inlinekeyboardmarkup
|
||||
telegram.inlinequery
|
||||
telegram.inlinequeryresult
|
||||
telegram.inlinequeryresultarticle
|
||||
telegram.inlinequeryresultaudio
|
||||
telegram.inlinequeryresultcachedaudio
|
||||
@@ -26,6 +42,7 @@ Submodules
|
||||
telegram.inlinequeryresultcachedvoice
|
||||
telegram.inlinequeryresultcontact
|
||||
telegram.inlinequeryresultdocument
|
||||
telegram.inlinequeryresultgame
|
||||
telegram.inlinequeryresultgif
|
||||
telegram.inlinequeryresultlocation
|
||||
telegram.inlinequeryresultmpeg4gif
|
||||
@@ -33,28 +50,29 @@ Submodules
|
||||
telegram.inlinequeryresultvenue
|
||||
telegram.inlinequeryresultvideo
|
||||
telegram.inlinequeryresultvoice
|
||||
telegram.choseninlineresult
|
||||
telegram.chataction
|
||||
telegram.contact
|
||||
telegram.document
|
||||
telegram.emoji
|
||||
telegram.error
|
||||
telegram.forcereply
|
||||
telegram.chat
|
||||
telegram.inputcontactmessagecontent
|
||||
telegram.inputfile
|
||||
telegram.inputlocationmessagecontent
|
||||
telegram.inputmessagecontent
|
||||
telegram.inputtextmessagecontent
|
||||
telegram.inputvenuemessagecontent
|
||||
telegram.keyboardbutton
|
||||
telegram.location
|
||||
telegram.message
|
||||
telegram.nullhandler
|
||||
telegram.messageentity
|
||||
telegram.parsemode
|
||||
telegram.photosize
|
||||
telegram.replykeyboardhide
|
||||
telegram.replykeyboardremove
|
||||
telegram.replykeyboardmarkup
|
||||
telegram.replymarkup
|
||||
telegram.sticker
|
||||
telegram.update
|
||||
telegram.user
|
||||
telegram.userprofilephotos
|
||||
telegram.venue
|
||||
telegram.video
|
||||
telegram.voice
|
||||
telegram.webhookinfo
|
||||
|
||||
Module contents
|
||||
---------------
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
telegram.venue module
|
||||
=====================
|
||||
|
||||
.. automodule:: telegram.venue
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
@@ -1,7 +1,7 @@
|
||||
telegram.nullhandler module
|
||||
telegram.webhookinfo module
|
||||
===========================
|
||||
|
||||
.. automodule:: telegram.nullhandler
|
||||
.. automodule:: telegram.webhookinfo
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
+2
-2
@@ -11,10 +11,10 @@ This is probably the base for most of the bots made with `python-telegram-bot`.
|
||||
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.
|
||||
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`
|
||||
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!
|
||||
|
||||
### [`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.
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 82 KiB |
@@ -17,7 +17,7 @@ Press Ctrl-C on the command line or send a signal to the process to stop the
|
||||
bot.
|
||||
"""
|
||||
|
||||
from telegram import (ReplyKeyboardMarkup)
|
||||
from telegram import (ReplyKeyboardMarkup, ReplyKeyboardRemove)
|
||||
from telegram.ext import (Updater, CommandHandler, MessageHandler, Filters, RegexHandler,
|
||||
ConversationHandler)
|
||||
|
||||
@@ -48,7 +48,8 @@ def gender(bot, update):
|
||||
user = update.message.from_user
|
||||
logger.info("Gender of %s: %s" % (user.first_name, update.message.text))
|
||||
update.message.reply_text('I see! Please send me a photo of yourself, '
|
||||
'so I know what you look like, or send /skip if you don\'t want to.')
|
||||
'so I know what you look like, or send /skip if you don\'t want to.',
|
||||
reply_markup=ReplyKeyboardRemove())
|
||||
|
||||
return PHOTO
|
||||
|
||||
@@ -104,7 +105,8 @@ def bio(bot, update):
|
||||
def cancel(bot, update):
|
||||
user = update.message.from_user
|
||||
logger.info("User %s canceled the conversation." % user.first_name)
|
||||
update.message.reply_text('Bye! I hope we can talk again some day.')
|
||||
update.message.reply_text('Bye! I hope we can talk again some day.',
|
||||
reply_markup=ReplyKeyboardRemove())
|
||||
|
||||
return ConversationHandler.END
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 82 KiB |
@@ -30,7 +30,7 @@ with codecs.open('README.rst', 'r', 'utf-8') as fd:
|
||||
license='LGPLv3',
|
||||
url='https://python-telegram-bot.org/',
|
||||
keywords='python telegram bot api wrapper',
|
||||
description='Not just a Python wrapper around the Telegram Bot API',
|
||||
description="We have made you a wrapper you can't refuse",
|
||||
long_description=fd.read(),
|
||||
packages=find_packages(exclude=['tests*']),
|
||||
install_requires=requirements(),
|
||||
|
||||
@@ -38,7 +38,7 @@ from .userprofilephotos import UserProfilePhotos
|
||||
from .keyboardbutton import KeyboardButton
|
||||
from .replymarkup import ReplyMarkup
|
||||
from .replykeyboardmarkup import ReplyKeyboardMarkup
|
||||
from .replykeyboardhide import ReplyKeyboardHide
|
||||
from .replykeyboardremove import ReplyKeyboardRemove, ReplyKeyboardHide
|
||||
from .forcereply import ForceReply
|
||||
from .error import TelegramError
|
||||
from .inputfile import InputFile
|
||||
@@ -106,9 +106,9 @@ __all__ = [
|
||||
'InlineQueryResultVoice', 'InlineQueryResultGame', 'InputContactMessageContent', 'InputFile',
|
||||
'InputLocationMessageContent', 'InputMessageContent', 'InputTextMessageContent',
|
||||
'InputVenueMessageContent', 'KeyboardButton', 'Location', 'Message', 'MessageEntity',
|
||||
'ParseMode', 'PhotoSize', 'ReplyKeyboardHide', 'ReplyKeyboardMarkup', 'ReplyMarkup', 'Sticker',
|
||||
'TelegramError', 'TelegramObject', 'Update', 'User', 'UserProfilePhotos', 'Venue', 'Video',
|
||||
'Voice', 'MAX_MESSAGE_LENGTH', 'MAX_CAPTION_LENGTH', 'SUPPORTED_WEBHOOK_PORTS',
|
||||
'ParseMode', 'PhotoSize', 'ReplyKeyboardRemove', 'ReplyKeyboardMarkup', 'ReplyMarkup',
|
||||
'Sticker', 'TelegramError', 'TelegramObject', 'Update', 'User', 'UserProfilePhotos', 'Venue',
|
||||
'Video', 'Voice', 'MAX_MESSAGE_LENGTH', 'MAX_CAPTION_LENGTH', 'SUPPORTED_WEBHOOK_PORTS',
|
||||
'MAX_FILESIZE_DOWNLOAD', 'MAX_FILESIZE_UPLOAD', 'MAX_MESSAGES_PER_SECOND_PER_CHAT',
|
||||
'MAX_MESSAGES_PER_SECOND', 'MAX_MESSAGES_PER_MINUTE_PER_GROUP', 'WebhookInfo', 'Animation',
|
||||
'Game', 'GameHighScore'
|
||||
|
||||
@@ -14,5 +14,10 @@ def print_ver_info():
|
||||
print('future {0}'.format(future.__version__))
|
||||
print('Python {0}'.format(sys.version.replace('\n', ' ')))
|
||||
|
||||
# main
|
||||
print_ver_info()
|
||||
|
||||
def main():
|
||||
print_ver_info()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
+64
-25
@@ -21,6 +21,7 @@
|
||||
|
||||
import functools
|
||||
import logging
|
||||
import warnings
|
||||
|
||||
from telegram import (User, Message, Update, Chat, ChatMember, UserProfilePhotos, File,
|
||||
ReplyMarkup, TelegramObject, WebhookInfo, GameHighScore)
|
||||
@@ -208,7 +209,7 @@ class Bot(TelegramObject):
|
||||
ID of the original message.
|
||||
reply_markup (Optional[:class:`telegram.ReplyMarkup`]): Additional
|
||||
interface options. A JSON-serialized object for an inline
|
||||
keyboard, custom reply keyboard, instructions to hide reply
|
||||
keyboard, custom reply keyboard, instructions to remove reply
|
||||
keyboard or to force a reply from the user.
|
||||
timeout (Optional[float]): If this value is specified, use it as
|
||||
the definitive timeout (in seconds) for urlopen() operations.
|
||||
@@ -299,7 +300,7 @@ class Bot(TelegramObject):
|
||||
message.
|
||||
reply_markup (Optional[:class:`telegram.ReplyMarkup`]): Additional interface options. A
|
||||
JSON-serialized object for an inline keyboard, custom reply keyboard, instructions
|
||||
to hide reply keyboard or to force a reply from the user.
|
||||
to remove reply keyboard or to force a reply from the user.
|
||||
timeout (Optional[float]): If this value is specified, use it as the definitive timeout
|
||||
(in seconds) for urlopen() operations.
|
||||
**kwargs (dict): Arbitrary keyword arguments.
|
||||
@@ -347,20 +348,20 @@ class Bot(TelegramObject):
|
||||
|
||||
Args:
|
||||
chat_id: Unique identifier for the message recipient - Chat id.
|
||||
audio Audio file to send. You can either pass a file_id as String to resend an audio
|
||||
audio: Audio file to send. You can either pass a file_id as String to resend an audio
|
||||
that is already on the Telegram servers, or upload a new audio file using
|
||||
multipart/form-data.
|
||||
duration (Optional[int]): Duration of sent audio in seconds.
|
||||
performer: Performer of sent audio. [Optional]
|
||||
title: Title of sent audio. [Optional]
|
||||
caption: Audio caption [Optional]
|
||||
performer (Optional[str]): Performer of sent audio.
|
||||
title (Optional[str]): Title of sent audio.
|
||||
caption (Optional[str]): Audio caption
|
||||
disable_notification (Optional[bool]): Sends the message silently. iOS users will not
|
||||
receive a notification, Android users will receive a notification with no sound.
|
||||
reply_to_message_id (Optional[int]): If the message is a reply, ID of the original
|
||||
message.
|
||||
reply_markup (Optional[:class:`telegram.ReplyMarkup`]): Additional interface options. A
|
||||
JSON-serialized object for an inline keyboard, custom reply keyboard, instructions
|
||||
to hide reply keyboard or to force a reply from the user.
|
||||
to remove reply keyboard or to force a reply from the user.
|
||||
timeout (Optional[float]): If this value is specified, use it as the definitive timeout
|
||||
(in seconds) for urlopen() operations.
|
||||
**kwargs (dict): Arbitrary keyword arguments.
|
||||
@@ -405,8 +406,8 @@ class Bot(TelegramObject):
|
||||
chat_id: Unique identifier for the message recipient - Chat id.
|
||||
document: File to send. You can either pass a file_id as String to resend a file that
|
||||
is already on the Telegram servers, or upload a new file using multipart/form-data.
|
||||
filename: File name that shows in telegram message (it is usefull when you send file
|
||||
generated by temp module, for example). [Optional]
|
||||
filename (Optional[str]): File name that shows in telegram message (it is usefull when
|
||||
you send file generated by temp module, for example).
|
||||
caption (Optional[str]): Document caption (may also be used when resending documents by
|
||||
file_id), 0-200 characters.
|
||||
disable_notification (Optional[bool]): Sends the message silently. iOS users will not
|
||||
@@ -415,7 +416,7 @@ class Bot(TelegramObject):
|
||||
message.
|
||||
reply_markup (Optional[:class:`telegram.ReplyMarkup`]): Additional interface options. A
|
||||
JSON-serialized object for an inline keyboard, custom reply keyboard, instructions
|
||||
to hide reply keyboard or to force a reply from the user.
|
||||
to remove reply keyboard or to force a reply from the user.
|
||||
timeout (Optional[float]): If this value is specified, use it as the definitive timeout
|
||||
(in seconds) for urlopen() operations.
|
||||
**kwargs (dict): Arbitrary keyword arguments.
|
||||
@@ -461,7 +462,7 @@ class Bot(TelegramObject):
|
||||
message.
|
||||
reply_markup (Optional[:class:`telegram.ReplyMarkup`]): Additional interface options. A
|
||||
JSON-serialized object for an inline keyboard, custom reply keyboard, instructions
|
||||
to hide reply keyboard or to force a reply from the user.
|
||||
to remove reply keyboard or to force a reply from the user.
|
||||
timeout (Optional[float]): If this value is specified, use it as the definitive timeout
|
||||
(in seconds) for urlopen() operations.
|
||||
**kwargs (dict): Arbitrary keyword arguments.
|
||||
@@ -508,7 +509,7 @@ class Bot(TelegramObject):
|
||||
message.
|
||||
reply_markup (Optional[:class:`telegram.ReplyMarkup`]): Additional interface options. A
|
||||
JSON-serialized object for an inline keyboard, custom reply keyboard, instructions
|
||||
to hide reply keyboard or to force a reply from the user.
|
||||
to remove reply keyboard or to force a reply from the user.
|
||||
timeout (Optional[float]): If this value is specified, use it as the definitive timeout
|
||||
(in seconds) for urlopen() operations.
|
||||
|
||||
@@ -554,14 +555,14 @@ class Bot(TelegramObject):
|
||||
that is already on the Telegram servers, or upload a new audio file using
|
||||
multipart/form-data.
|
||||
duration (Optional[int]): Duration of sent audio in seconds.
|
||||
caption: Voice caption [Optional]
|
||||
caption (Optional[str]): Voice caption
|
||||
disable_notification (Optional[bool]): Sends the message silently. iOS users will not
|
||||
receive a notification, Android users will receive a notification with no sound.
|
||||
reply_to_message_id (Optional[int]): If the message is a reply, ID of the original
|
||||
message.
|
||||
reply_markup (Optional[:class:`telegram.ReplyMarkup`]): Additional interface options. A
|
||||
JSON-serialized object for an inline keyboard, custom reply keyboard, instructions
|
||||
to hide reply keyboard or to force a reply from the user.
|
||||
to remove reply keyboard or to force a reply from the user.
|
||||
timeout (Optional[float]): If this value is specified, use it as the definitive timeout
|
||||
(in seconds) for urlopen() operations.
|
||||
**kwargs (dict): Arbitrary keyword arguments.
|
||||
@@ -607,7 +608,7 @@ class Bot(TelegramObject):
|
||||
message.
|
||||
reply_markup (Optional[:class:`telegram.ReplyMarkup`]): Additional interface options. A
|
||||
JSON-serialized object for an inline keyboard, custom reply keyboard, instructions
|
||||
to hide reply keyboard or to force a reply from the user.
|
||||
to remove reply keyboard or to force a reply from the user.
|
||||
timeout (Optional[float]): If this value is specified, use it as the definitive timeout
|
||||
(in seconds) for urlopen() operations.
|
||||
**kwargs (dict): Arbitrary keyword arguments.
|
||||
@@ -656,7 +657,7 @@ class Bot(TelegramObject):
|
||||
message.
|
||||
reply_markup (Optional[:class:`telegram.ReplyMarkup`]): Additional interface options. A
|
||||
JSON-serialized object for an inline keyboard, custom reply keyboard, instructions
|
||||
to hide reply keyboard or to force a reply from the user.
|
||||
to remove reply keyboard or to force a reply from the user.
|
||||
timeout (Optional[float]): If this value is specified, use it as the definitive timeout
|
||||
(in seconds) for urlopen() operations.
|
||||
**kwargs (dict): Arbitrary keyword arguments.
|
||||
@@ -710,7 +711,7 @@ class Bot(TelegramObject):
|
||||
message.
|
||||
reply_markup (Optional[:class:`telegram.ReplyMarkup`]): Additional interface options. A
|
||||
JSON-serialized object for an inline keyboard, custom reply keyboard, instructions
|
||||
to hide reply keyboard or to force a reply from the user.
|
||||
to remove reply keyboard or to force a reply from the user.
|
||||
timeout (Optional[float]): If this value is specified, use it as the definitive timeout
|
||||
(in seconds) for urlopen() operations.
|
||||
**kwargs (dict): Arbitrary keyword arguments.
|
||||
@@ -749,7 +750,7 @@ class Bot(TelegramObject):
|
||||
ID of the original message.
|
||||
reply_markup (Optional[:class:`telegram.ReplyMarkup`]): Additional interface options.
|
||||
A JSON-serialized object for an inline keyboard, custom reply keyboard,
|
||||
instructions to hide reply keyboard or to force a reply from the user.
|
||||
instructions to remove reply keyboard or to force a reply from the user.
|
||||
timeout (Optional[float]): If this value is specified, use it as
|
||||
the definitive timeout (in seconds) for urlopen() operations.
|
||||
|
||||
@@ -777,6 +778,7 @@ class Bot(TelegramObject):
|
||||
chat_id: Unique identifier for the message recipient - Chat id.
|
||||
action: Type of action to broadcast. Choose one, depending on what the user is about to
|
||||
receive:
|
||||
|
||||
- ChatAction.TYPING for text messages,
|
||||
- ChatAction.UPLOAD_PHOTO for photos,
|
||||
- ChatAction.UPLOAD_VIDEO for videos,
|
||||
@@ -862,8 +864,8 @@ class Bot(TelegramObject):
|
||||
|
||||
Args:
|
||||
user_id: Unique identifier of the target user.
|
||||
offset (Optional[int]: Sequential number of the first photo to be returned. By default,
|
||||
all photos are returned.
|
||||
offset (Optional[int]): Sequential number of the first photo to be returned. By
|
||||
default, all photos are returned.
|
||||
limit (Optional[int]): Limits the number of photos to be retrieved. Values between
|
||||
1-100 are accepted. Defaults to 100.
|
||||
timeout (Optional[float]): If this value is specified, use it as the definitive timeout
|
||||
@@ -960,7 +962,7 @@ class Bot(TelegramObject):
|
||||
Args:
|
||||
chat_id: Unique identifier for the target group or username of the target supergroup
|
||||
(in the format @supergroupusername).
|
||||
user_id: Unique identifier of the target user.
|
||||
user_id: Unique identifier of the target user.
|
||||
timeout (Optional[float]): If this value is specified, use it as the definitive timeout
|
||||
(in seconds) for urlopen() operations.
|
||||
**kwargs (dict): Arbitrary keyword arguments.
|
||||
@@ -986,6 +988,7 @@ class Bot(TelegramObject):
|
||||
text=None,
|
||||
show_alert=False,
|
||||
url=None,
|
||||
cache_time=None,
|
||||
timeout=None,
|
||||
**kwargs):
|
||||
"""Use this method to send answers to callback queries sent from inline keyboards. The
|
||||
@@ -998,9 +1001,12 @@ class Bot(TelegramObject):
|
||||
to the user.
|
||||
show_alert (Optional[bool]): If `True`, an alert will be shown by the client instead of
|
||||
a notification at the top of the chat screen. Defaults to `False`.
|
||||
url (Optional[str]): URL that will be opened by the user's client.
|
||||
cache_time (Optional[int]): The maximum amount of time in seconds that the result of
|
||||
the callback query may be cached client-side. Telegram apps will support caching
|
||||
starting in version 3.14. Defaults to 0.
|
||||
timeout (Optional[float]): If this value is specified, use it as the definitive timeout
|
||||
(in seconds) for urlopen() operations.
|
||||
url (Optional[str]): URL that will be opened by the user's client.
|
||||
**kwargs (dict): Arbitrary keyword arguments.
|
||||
|
||||
Returns:
|
||||
@@ -1020,6 +1026,8 @@ class Bot(TelegramObject):
|
||||
data['show_alert'] = show_alert
|
||||
if url:
|
||||
data['url'] = url
|
||||
if cache_time is not None:
|
||||
data['cache_time'] = cache_time
|
||||
|
||||
result = self._request.post(url_, data, timeout=timeout)
|
||||
|
||||
@@ -1053,7 +1061,7 @@ class Bot(TelegramObject):
|
||||
reply_markup: A JSON-serialized object for an inline keyboard.
|
||||
reply_markup (Optional[:class:`telegram.ReplyMarkup`]): Additional interface options. A
|
||||
JSON-serialized object for an inline keyboard, custom reply keyboard, instructions
|
||||
to hide reply keyboard or to force a reply from the user.
|
||||
to remove reply keyboard or to force a reply from the user.
|
||||
timeout (Optional[float]): If this value is specified, use it as the definitive timeout
|
||||
(in seconds) for urlopen() operations.
|
||||
**kwargs (dict): Arbitrary keyword arguments.
|
||||
@@ -1433,9 +1441,32 @@ class Bot(TelegramObject):
|
||||
message_id=None,
|
||||
inline_message_id=None,
|
||||
edit_message=None,
|
||||
force=None,
|
||||
disable_edit_message=None,
|
||||
**kwargs):
|
||||
"""Use this method to set the score of the specified user in a game.
|
||||
|
||||
Args:
|
||||
user_id (int): User identifier.
|
||||
score (int): New score, must be non-negative.
|
||||
chat_id (Optional[int|str]): Required if `inline_message_id` is not specified. Unique
|
||||
identifier for the target chat (or username of the target channel in the format
|
||||
`@channelusername`)
|
||||
message_id (Optional[int]): Required if inline_message_id is not specified. Identifier
|
||||
of the sent message.
|
||||
inline_message_id (Optional[str]): Required if chat_id and message_id are not
|
||||
specified. Identifier of the inline message.
|
||||
force (Optional[bool]): Pass True, if the high score is allowed to decrease. This can
|
||||
be useful when fixing mistakes or banning cheaters.
|
||||
disable_edit_message (Optional[bool]): Pass True, if the game message should not be
|
||||
automatically edited to include the current scoreboard.
|
||||
edit_message (Optional[bool]): Deprecated. Has the opposite logic for
|
||||
`disable_edit_message`.
|
||||
|
||||
Keyword Args:
|
||||
timeout (Optional[float]): If this value is specified, use it as the definitive timeout
|
||||
(in seconds) for urlopen() operations.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message` or True: The edited message, or if the
|
||||
message wasn't sent by the bot, True.
|
||||
@@ -1451,8 +1482,16 @@ class Bot(TelegramObject):
|
||||
data['message_id'] = message_id
|
||||
if inline_message_id:
|
||||
data['inline_message_id'] = inline_message_id
|
||||
if edit_message:
|
||||
data['edit_message'] = edit_message
|
||||
if force is not None:
|
||||
data['force'] = force
|
||||
if disable_edit_message is not None:
|
||||
data['disable_edit_message'] = disable_edit_message
|
||||
if edit_message is not None:
|
||||
warnings.warn('edit_message is deprecated, use disable_edit_message instead')
|
||||
if disable_edit_message is None:
|
||||
data['edit_message'] = edit_message
|
||||
else:
|
||||
warnings.warn('edit_message is ignored when disable_edit_message is used')
|
||||
|
||||
result = self._request.post(url, data, timeout=kwargs.get('timeout'))
|
||||
if result is True:
|
||||
|
||||
@@ -39,7 +39,7 @@ class CallbackQueryHandler(Handler):
|
||||
pass_update_queue (optional[bool]): If set to ``True``, a keyword argument called
|
||||
``update_queue`` will be passed to the callback function. It will be the ``Queue``
|
||||
instance used by the ``Updater`` and ``Dispatcher`` that contains new updates which can
|
||||
be used to insert updates. Default is ``False``.
|
||||
be used to insert updates. Default is ``False``.
|
||||
pass_job_queue (optional[bool]): If set to ``True``, a keyword argument called
|
||||
``job_queue`` will be passed to the callback function. It will be a ``JobQueue``
|
||||
instance created by the ``Updater`` which can be used to schedule new jobs.
|
||||
|
||||
@@ -35,7 +35,7 @@ class ChosenInlineResultHandler(Handler):
|
||||
pass_update_queue (optional[bool]): If set to ``True``, a keyword argument called
|
||||
``update_queue`` will be passed to the callback function. It will be the ``Queue``
|
||||
instance used by the ``Updater`` and ``Dispatcher`` that contains new updates which can
|
||||
be used to insert updates. Default is ``False``.
|
||||
be used to insert updates. Default is ``False``.
|
||||
pass_job_queue (optional[bool]): If set to ``True``, a keyword argument called
|
||||
``job_queue`` will be passed to the callback function. It will be a ``JobQueue``
|
||||
instance created by the ``Updater`` which can be used to schedule new jobs.
|
||||
|
||||
@@ -44,7 +44,7 @@ class CommandHandler(Handler):
|
||||
pass_update_queue (optional[bool]): If set to ``True``, a keyword argument called
|
||||
``update_queue`` will be passed to the callback function. It will be the ``Queue``
|
||||
instance used by the ``Updater`` and ``Dispatcher`` that contains new updates which can
|
||||
be used to insert updates. Default is ``False``.
|
||||
be used to insert updates. Default is ``False``.
|
||||
pass_job_queue (optional[bool]): If set to ``True``, a keyword argument called
|
||||
``job_queue`` will be passed to the callback function. It will be a ``JobQueue``
|
||||
instance created by the ``Updater`` which can be used to schedule new jobs.
|
||||
|
||||
@@ -309,7 +309,7 @@ class Dispatcher(object):
|
||||
which handlers were added to the group defines the priority.
|
||||
|
||||
Args:
|
||||
handler (Handler): A Handler instance
|
||||
handler (telegram.ext.Handler): A Handler instance
|
||||
group (Optional[int]): The group identifier. Default is 0
|
||||
"""
|
||||
|
||||
@@ -330,7 +330,7 @@ class Dispatcher(object):
|
||||
Remove a handler from the specified group
|
||||
|
||||
Args:
|
||||
handler (Handler): A Handler instance
|
||||
handler (telegram.ext.Handler): A Handler instance
|
||||
group (optional[object]): The group identifier. Default is 0
|
||||
"""
|
||||
if handler in self.handlers[group]:
|
||||
|
||||
@@ -107,6 +107,13 @@ class Filters(object):
|
||||
def filter(self, message):
|
||||
return bool(message.text and message.text.startswith('/'))
|
||||
|
||||
class _Reply(BaseFilter):
|
||||
|
||||
def filter(self, message):
|
||||
return bool(message.reply_to_message)
|
||||
|
||||
reply = _Reply()
|
||||
|
||||
command = _Command()
|
||||
|
||||
class _Audio(BaseFilter):
|
||||
|
||||
@@ -35,7 +35,7 @@ class Handler(object):
|
||||
pass_update_queue (optional[bool]): If set to ``True``, a keyword argument called
|
||||
``update_queue`` will be passed to the callback function. It will be the ``Queue``
|
||||
instance used by the ``Updater`` and ``Dispatcher`` that contains new updates which can
|
||||
be used to insert updates. Default is ``False``.
|
||||
be used to insert updates. Default is ``False``.
|
||||
pass_job_queue (optional[bool]): If set to ``True``, a keyword argument called
|
||||
``job_queue`` will be passed to the callback function. It will be a ``JobQueue``
|
||||
instance created by the ``Updater`` which can be used to schedule new jobs.
|
||||
@@ -85,7 +85,7 @@ class Handler(object):
|
||||
|
||||
Args:
|
||||
update (object): The update to be handled
|
||||
dispatcher (Dispatcher): The dispatcher to collect optional args
|
||||
dispatcher (telegram.ext.Dispatcher): The dispatcher to collect optional args
|
||||
|
||||
"""
|
||||
raise NotImplementedError
|
||||
@@ -96,7 +96,7 @@ class Handler(object):
|
||||
handlers
|
||||
|
||||
Args:
|
||||
dispatcher (Dispatcher):
|
||||
dispatcher (telegram.ext.Dispatcher):
|
||||
"""
|
||||
optional_args = dict()
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ class InlineQueryHandler(Handler):
|
||||
pass_update_queue (optional[bool]): If set to ``True``, a keyword argument called
|
||||
``update_queue`` will be passed to the callback function. It will be the ``Queue``
|
||||
instance used by the ``Updater`` and ``Dispatcher`` that contains new updates which can
|
||||
be used to insert updates. Default is ``False``.
|
||||
be used to insert updates. Default is ``False``.
|
||||
pass_job_queue (optional[bool]): If set to ``True``, a keyword argument called
|
||||
``job_queue`` will be passed to the callback function. It will be a ``JobQueue``
|
||||
instance created by the ``Updater`` which can be used to schedule new jobs.
|
||||
|
||||
+44
-13
@@ -21,19 +21,26 @@
|
||||
import logging
|
||||
import time
|
||||
import warnings
|
||||
import datetime
|
||||
from numbers import Number
|
||||
from threading import Thread, Lock, Event
|
||||
from queue import PriorityQueue, Empty
|
||||
|
||||
|
||||
class Days(object):
|
||||
MON, TUE, WED, THU, FRI, SAT, SUN = range(7)
|
||||
EVERY_DAY = tuple(range(7))
|
||||
|
||||
|
||||
class JobQueue(object):
|
||||
"""This class allows you to periodically perform tasks with the bot.
|
||||
|
||||
Attributes:
|
||||
queue (PriorityQueue):
|
||||
bot (Bot):
|
||||
bot (telegram.Bot):
|
||||
|
||||
Args:
|
||||
bot (Bot): The bot instance that should be passed to the jobs
|
||||
bot (telegram.Bot): The bot instance that should be passed to the jobs
|
||||
|
||||
Deprecated: 5.2
|
||||
prevent_autostart (Optional[bool]): Thread does not start during initialisation.
|
||||
@@ -60,15 +67,26 @@ class JobQueue(object):
|
||||
"""Queue a new job.
|
||||
|
||||
Args:
|
||||
job (Job): The ``Job`` instance representing the new job
|
||||
next_t (Optional[float]): Time in seconds in which the job should be executed first.
|
||||
Defaults to ``job.interval``
|
||||
job (telegram.ext.Job): The ``Job`` instance representing the new job
|
||||
next_t (Optional[int, float, datetime.timedelta]): Time in which the job
|
||||
should be executed first. Defaults to ``job.interval``. ``int`` and ``float``
|
||||
will be interpreted as seconds.
|
||||
|
||||
"""
|
||||
job.job_queue = self
|
||||
|
||||
if next_t is None:
|
||||
next_t = job.interval
|
||||
interval = job.interval
|
||||
|
||||
if isinstance(interval, Number):
|
||||
next_t = interval
|
||||
elif isinstance(interval, datetime.timedelta):
|
||||
next_t = interval.total_seconds()
|
||||
else:
|
||||
raise ValueError("The interval argument should be of type datetime.timedelta,"
|
||||
" int or float")
|
||||
elif isinstance(next_t, datetime.timedelta):
|
||||
next_t = next_t.total_second()
|
||||
|
||||
now = time.time()
|
||||
next_t += now
|
||||
@@ -123,11 +141,11 @@ class JobQueue(object):
|
||||
continue
|
||||
|
||||
if job.enabled:
|
||||
self.logger.debug('Running job %s', job.name)
|
||||
|
||||
try:
|
||||
job.run(self.bot)
|
||||
|
||||
current_week_day = datetime.datetime.now().weekday()
|
||||
if any(day == current_week_day for day in job.days):
|
||||
self.logger.debug('Running job %s', job.name)
|
||||
job.run(self.bot)
|
||||
except:
|
||||
self.logger.exception('An uncaught error was raised while executing job %s',
|
||||
job.name)
|
||||
@@ -200,6 +218,7 @@ class Job(object):
|
||||
Attributes:
|
||||
callback (function):
|
||||
interval (float):
|
||||
days: (tuple)
|
||||
repeat (bool):
|
||||
name (str):
|
||||
enabled (bool): Boolean property that decides if this job is currently active
|
||||
@@ -208,22 +227,34 @@ class Job(object):
|
||||
callback (function): The callback function that should be executed by the Job. It should
|
||||
take two parameters ``bot`` and ``job``, where ``job`` is the ``Job`` instance. It
|
||||
can be used to terminate the job or modify its interval.
|
||||
interval (float): The interval in which this job should execute its callback function in
|
||||
seconds.
|
||||
interval ([int, float, datetime.timedelta]): The interval in which the job will execute its
|
||||
callback function. ``int`` and ``float`` will be interpreted as seconds.
|
||||
repeat (Optional[bool]): If this job should be periodically execute its callback function
|
||||
(``True``) or only once (``False``). Defaults to ``True``
|
||||
context (Optional[object]): Additional data needed for the callback function. Can be
|
||||
accessed through ``job.context`` in the callback. Defaults to ``None``
|
||||
days (Tuple): Defines on which days the job should be ran.
|
||||
|
||||
"""
|
||||
job_queue = None
|
||||
|
||||
def __init__(self, callback, interval, repeat=True, context=None):
|
||||
def __init__(self, callback, interval, repeat=True, context=None, days=Days.EVERY_DAY):
|
||||
self.callback = callback
|
||||
self.interval = interval
|
||||
self.repeat = repeat
|
||||
self.context = context
|
||||
|
||||
if not isinstance(days, tuple):
|
||||
raise ValueError("The 'days argument should be of type 'tuple'")
|
||||
|
||||
if not all(isinstance(day, int) for day in days):
|
||||
raise ValueError("The elements of the 'days' argument should be of type 'int'")
|
||||
|
||||
if not all(day >= 0 and day <= 6 for day in days):
|
||||
raise ValueError("The elements of the 'days' argument should be from 0 up to and "
|
||||
"including 6")
|
||||
|
||||
self.days = days
|
||||
self.name = callback.__name__
|
||||
self._remove = Event()
|
||||
self._enabled = Event()
|
||||
|
||||
@@ -32,8 +32,8 @@ class MessageHandler(Handler):
|
||||
|
||||
Args:
|
||||
filters (telegram.ext.BaseFilter): A filter inheriting from
|
||||
:class:`telegram.filters.BaseFilter`. Standard filters can be found in
|
||||
:class:`telegram.filters.Filters`. Filters can be combined using bitwise
|
||||
:class:`telegram.ext.filters.BaseFilter`. Standard filters can be found in
|
||||
:class:`telegram.ext.filters.Filters`. Filters can be combined using bitwise
|
||||
operators (& for and, | for or).
|
||||
callback (function): A function that takes ``bot, update`` as
|
||||
positional arguments. It will be called when the ``check_update``
|
||||
@@ -51,6 +51,11 @@ class MessageHandler(Handler):
|
||||
``chat_data`` will be passed to the callback function. It will be a ``dict`` you
|
||||
can use to keep any data related to the chat that the update was sent in.
|
||||
For each update in the same chat, it will be the same ``dict``. Default is ``False``.
|
||||
message_updates (Optional[bool]): Should "normal" message updates be handled? Default is
|
||||
``True``.
|
||||
channel_posts_updates (Optional[bool]): Should channel posts updates be handled? Default is
|
||||
``True``.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
@@ -60,7 +65,12 @@ class MessageHandler(Handler):
|
||||
pass_update_queue=False,
|
||||
pass_job_queue=False,
|
||||
pass_user_data=False,
|
||||
pass_chat_data=False):
|
||||
pass_chat_data=False,
|
||||
message_updates=True,
|
||||
channel_posts_updates=True):
|
||||
if not message_updates and not channel_posts_updates:
|
||||
raise ValueError('Both message_updates & channel_post_updates are False')
|
||||
|
||||
super(MessageHandler, self).__init__(
|
||||
callback,
|
||||
pass_update_queue=pass_update_queue,
|
||||
@@ -69,6 +79,8 @@ class MessageHandler(Handler):
|
||||
pass_chat_data=pass_chat_data)
|
||||
self.filters = filters
|
||||
self.allow_edited = allow_edited
|
||||
self.message_updates = message_updates
|
||||
self.channel_posts_updates = channel_posts_updates
|
||||
|
||||
# We put this up here instead of with the rest of checking code
|
||||
# in check_update since we don't wanna spam a ton
|
||||
@@ -77,15 +89,24 @@ class MessageHandler(Handler):
|
||||
'deprecated, please use bitwise operators (& and |) '
|
||||
'instead. More info: https://git.io/vPTbc.')
|
||||
|
||||
def _is_allowed_message(self, update):
|
||||
return (self.message_updates
|
||||
and (update.message or (update.edited_message and self.allow_edited)))
|
||||
|
||||
def _is_allowed_channel_post(self, update):
|
||||
return (self.channel_posts_updates
|
||||
and (update.channel_post or (update.edited_channel_post and self.allow_edited)))
|
||||
|
||||
def check_update(self, update):
|
||||
if (isinstance(update, Update)
|
||||
and (update.message or update.edited_message and self.allow_edited)):
|
||||
and (self._is_allowed_message(update) or self._is_allowed_channel_post(update))):
|
||||
|
||||
if not self.filters:
|
||||
res = True
|
||||
|
||||
else:
|
||||
message = update.message or update.edited_message
|
||||
message = (update.message or update.edited_message or update.channel_post
|
||||
or update.edited_channel_post)
|
||||
if isinstance(self.filters, list):
|
||||
res = any(func(message) for func in self.filters)
|
||||
else:
|
||||
|
||||
@@ -48,7 +48,7 @@ class RegexHandler(Handler):
|
||||
pass_update_queue (optional[bool]): If set to ``True``, a keyword argument called
|
||||
``update_queue`` will be passed to the callback function. It will be the ``Queue``
|
||||
instance used by the ``Updater`` and ``Dispatcher`` that contains new updates which can
|
||||
be used to insert updates. Default is ``False``.
|
||||
be used to insert updates. Default is ``False``.
|
||||
pass_job_queue (optional[bool]): If set to ``True``, a keyword argument called
|
||||
``job_queue`` will be passed to the callback function. It will be a ``JobQueue``
|
||||
instance created by the ``Updater`` which can be used to schedule new jobs.
|
||||
|
||||
@@ -40,7 +40,7 @@ class StringCommandHandler(Handler):
|
||||
pass_update_queue (optional[bool]): If set to ``True``, a keyword argument called
|
||||
``update_queue`` will be passed to the callback function. It will be the ``Queue``
|
||||
instance used by the ``Updater`` and ``Dispatcher`` that contains new updates which can
|
||||
be used to insert updates. Default is ``False``.
|
||||
be used to insert updates. Default is ``False``.
|
||||
pass_job_queue (optional[bool]): If set to ``True``, a keyword argument called
|
||||
``job_queue`` will be passed to the callback function. It will be a ``JobQueue``
|
||||
instance created by the ``Updater`` which can be used to schedule new jobs.
|
||||
|
||||
@@ -47,7 +47,7 @@ class StringRegexHandler(Handler):
|
||||
pass_update_queue (optional[bool]): If set to ``True``, a keyword argument called
|
||||
``update_queue`` will be passed to the callback function. It will be the ``Queue``
|
||||
instance used by the ``Updater`` and ``Dispatcher`` that contains new updates which can
|
||||
be used to insert updates. Default is ``False``.
|
||||
be used to insert updates. Default is ``False``.
|
||||
pass_job_queue (optional[bool]): If set to ``True``, a keyword argument called
|
||||
``job_queue`` will be passed to the callback function. It will be a ``JobQueue``
|
||||
instance created by the ``Updater`` which can be used to schedule new jobs.
|
||||
|
||||
@@ -37,7 +37,7 @@ class TypeHandler(Handler):
|
||||
pass_update_queue (optional[bool]): If set to ``True``, a keyword argument called
|
||||
``update_queue`` will be passed to the callback function. It will be the ``Queue``
|
||||
instance used by the ``Updater`` and ``Dispatcher`` that contains new updates which can
|
||||
be used to insert updates. Default is ``False``.
|
||||
be used to insert updates. Default is ``False``.
|
||||
pass_job_queue (optional[bool]): If set to ``True``, a keyword argument called
|
||||
``job_queue`` will be passed to the callback function. It will be a ``JobQueue``
|
||||
instance created by the ``Updater`` which can be used to schedule new jobs.
|
||||
|
||||
+2
-2
@@ -101,8 +101,8 @@ class Game(TelegramObject):
|
||||
(That is, you can't just slice ``Message.text`` with the offset and length.)
|
||||
|
||||
Args:
|
||||
entity (MessageEntity): The entity to extract the text from. It must be an entity that
|
||||
belongs to this message.
|
||||
entity (telegram.MessageEntity): The entity to extract the text from. It must be an
|
||||
entity that belongs to this message.
|
||||
|
||||
Returns:
|
||||
str: The text of the given entity
|
||||
|
||||
@@ -44,7 +44,7 @@ class InlineQueryResultCachedMpeg4Gif(InlineQueryResult):
|
||||
caption (Optional[str]):
|
||||
reply_markup (Optional[:class:`telegram.InlineKeyboardMarkup`]):
|
||||
input_message_content (Optional[:class:`telegram.InputMessageContent`]):
|
||||
**kwargs (dict): Arbitrary keyword arguments.
|
||||
**kwargs (dict): Arbitrary keyword arguments.
|
||||
|
||||
"""
|
||||
|
||||
|
||||
+72
-25
@@ -39,6 +39,7 @@ class Message(TelegramObject):
|
||||
date (:class:`datetime.datetime`):
|
||||
forward_from (:class:`telegram.User`):
|
||||
forward_from_chat (:class:`telegram.Chat`):
|
||||
forward_from_message_id (int):
|
||||
forward_date (:class:`datetime.datetime`):
|
||||
reply_to_message (:class:`telegram.Message`):
|
||||
edit_date (:class:`datetime.datetime`):
|
||||
@@ -76,11 +77,9 @@ class Message(TelegramObject):
|
||||
from_user (:class:`telegram.User`):
|
||||
date (:class:`datetime.datetime`):
|
||||
chat (:class:`telegram.Chat`):
|
||||
**kwargs: Arbitrary keyword arguments.
|
||||
|
||||
Keyword Args:
|
||||
forward_from (Optional[:class:`telegram.User`]):
|
||||
forward_from_chat (:class:`telegram.Chat`):
|
||||
forward_from_chat (Optional[:class:`telegram.Chat`]):
|
||||
forward_from_message_id (Optional[int]):
|
||||
forward_date (Optional[:class:`datetime.datetime`]):
|
||||
reply_to_message (Optional[:class:`telegram.Message`]):
|
||||
edit_date (Optional[:class:`datetime.datetime`]):
|
||||
@@ -141,6 +140,7 @@ class Message(TelegramObject):
|
||||
migrate_from_chat_id=0,
|
||||
channel_chat_created=False,
|
||||
pinned_message=None,
|
||||
forward_from_message_id=None,
|
||||
bot=None,
|
||||
**kwargs):
|
||||
# Required
|
||||
@@ -178,6 +178,7 @@ class Message(TelegramObject):
|
||||
self.migrate_from_chat_id = int(migrate_from_chat_id)
|
||||
self.channel_chat_created = bool(channel_chat_created)
|
||||
self.pinned_message = pinned_message
|
||||
self.forward_from_message_id = forward_from_message_id
|
||||
|
||||
self.bot = bot
|
||||
|
||||
@@ -326,6 +327,10 @@ class Message(TelegramObject):
|
||||
quote (Optional[bool]): If set to ``True``, the photo is sent as an actual reply to
|
||||
this message. If ``reply_to_message_id`` is passed in ``kwargs``, this parameter
|
||||
will be ignored. Default: ``True`` in group chats and ``False`` in private chats.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, instance representing the message posted.
|
||||
|
||||
"""
|
||||
|
||||
self._quote(kwargs)
|
||||
@@ -339,6 +344,10 @@ class Message(TelegramObject):
|
||||
quote (Optional[bool]): If set to ``True``, the audio is sent as an actual reply to
|
||||
this message. If ``reply_to_message_id`` is passed in ``kwargs``, this parameter
|
||||
will be ignored. Default: ``True`` in group chats and ``False`` in private chats.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, instance representing the message posted.
|
||||
|
||||
"""
|
||||
|
||||
self._quote(kwargs)
|
||||
@@ -352,6 +361,10 @@ class Message(TelegramObject):
|
||||
quote (Optional[bool]): If set to ``True``, the document is sent as an actual reply to
|
||||
this message. If ``reply_to_message_id`` is passed in ``kwargs``, this parameter
|
||||
will be ignored. Default: ``True`` in group chats and ``False`` in private chats.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, instance representing the message posted.
|
||||
|
||||
"""
|
||||
|
||||
self._quote(kwargs)
|
||||
@@ -365,6 +378,10 @@ class Message(TelegramObject):
|
||||
quote (Optional[bool]): If set to ``True``, the sticker is sent as an actual reply to
|
||||
this message. If ``reply_to_message_id`` is passed in ``kwargs``, this parameter
|
||||
will be ignored. Default: ``True`` in group chats and ``False`` in private chats.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, instance representing the message posted.
|
||||
|
||||
"""
|
||||
|
||||
self._quote(kwargs)
|
||||
@@ -378,6 +395,10 @@ class Message(TelegramObject):
|
||||
quote (Optional[bool]): If set to ``True``, the video is sent as an actual reply to
|
||||
this message. If ``reply_to_message_id`` is passed in ``kwargs``, this parameter
|
||||
will be ignored. Default: ``True`` in group chats and ``False`` in private chats.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, instance representing the message posted.
|
||||
|
||||
"""
|
||||
|
||||
self._quote(kwargs)
|
||||
@@ -391,6 +412,10 @@ class Message(TelegramObject):
|
||||
quote (Optional[bool]): If set to ``True``, the voice is sent as an actual reply to
|
||||
this message. If ``reply_to_message_id`` is passed in ``kwargs``, this parameter
|
||||
will be ignored. Default: ``True`` in group chats and ``False`` in private chats.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, instance representing the message posted.
|
||||
|
||||
"""
|
||||
|
||||
self._quote(kwargs)
|
||||
@@ -404,6 +429,10 @@ class Message(TelegramObject):
|
||||
quote (Optional[bool]): If set to ``True``, the location is sent as an actual reply to
|
||||
this message. If ``reply_to_message_id`` is passed in ``kwargs``, this parameter
|
||||
will be ignored. Default: ``True`` in group chats and ``False`` in private chats.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, instance representing the message posted.
|
||||
|
||||
"""
|
||||
|
||||
self._quote(kwargs)
|
||||
@@ -417,6 +446,10 @@ class Message(TelegramObject):
|
||||
quote (Optional[bool]): If set to ``True``, the venue is sent as an actual reply to
|
||||
this message. If ``reply_to_message_id`` is passed in ``kwargs``, this parameter
|
||||
will be ignored. Default: ``True`` in group chats and ``False`` in private chats.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, instance representing the message posted.
|
||||
|
||||
"""
|
||||
|
||||
self._quote(kwargs)
|
||||
@@ -430,6 +463,10 @@ class Message(TelegramObject):
|
||||
quote (Optional[bool]): If set to ``True``, the contact is sent as an actual reply to
|
||||
this message. If ``reply_to_message_id`` is passed in ``kwargs``, this parameter
|
||||
will be ignored. Default: ``True`` in group chats and ``False`` in private chats.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, instance representing the message posted.
|
||||
|
||||
"""
|
||||
|
||||
self._quote(kwargs)
|
||||
@@ -438,10 +475,13 @@ class Message(TelegramObject):
|
||||
def forward(self, chat_id, disable_notification=False):
|
||||
"""Shortcut for
|
||||
|
||||
bot.forwardMessage(chat_id=chat_id,
|
||||
from_chat_id=update.message.chat_id,
|
||||
disable_notification=disable_notification,
|
||||
message_id=update.message.message_id)
|
||||
>>> bot.forwardMessage(chat_id=chat_id,
|
||||
... from_chat_id=update.message.chat_id,
|
||||
... disable_notification=disable_notification,
|
||||
... message_id=update.message.message_id)
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, instance representing the message forwarded.
|
||||
|
||||
"""
|
||||
return self.bot.forwardMessage(
|
||||
@@ -452,44 +492,51 @@ class Message(TelegramObject):
|
||||
|
||||
def edit_text(self, *args, **kwargs):
|
||||
"""
|
||||
Shortcut for ``bot.editMessageText(chat_id=message.chat_id,
|
||||
message_id=message.message_id,
|
||||
*args, **kwargs)``
|
||||
Shortcut for
|
||||
|
||||
>>> bot.editMessageText(chat_id=message.chat_id,
|
||||
... message_id=message.message_id,
|
||||
... *args, **kwargs)
|
||||
|
||||
Note:
|
||||
You can only edit messages that the bot sent itself,
|
||||
therefore this method can only be used on the
|
||||
return value of the bot.send_* family of methods.
|
||||
return value of the ``bot.send_*`` family of methods.
|
||||
|
||||
"""
|
||||
return self.bot.edit_message_text(
|
||||
chat_id=self.chat_id, message_id=self.message_id, *args, **kwargs)
|
||||
|
||||
def edit_caption(self, *args, **kwargs):
|
||||
"""
|
||||
Shortcut for ``bot.editMessageCaption(chat_id=message.chat_id,
|
||||
message_id=message.message_id,
|
||||
*args, **kwargs)``
|
||||
Shortcut for
|
||||
|
||||
>>> bot.editMessageCaption(chat_id=message.chat_id,
|
||||
... message_id=message.message_id,
|
||||
... *args, **kwargs)
|
||||
|
||||
Note:
|
||||
You can only edit messages that the bot sent itself,
|
||||
therefore this method can only be used on the
|
||||
return value of the bot.send_* family of methods.
|
||||
return value of the ``bot.send_*`` family of methods.
|
||||
"""
|
||||
return self.bot.edit_message_caption(
|
||||
chat_id=self.chat_id, message_id=self.message_id, *args, **kwargs)
|
||||
|
||||
def edit_reply_markup(self, *args, **kwargs):
|
||||
"""
|
||||
Shortcut for ``bot.editReplyMarkup(chat_id=message.chat_id,
|
||||
message_id=message.message_id,
|
||||
*args, **kwargs)``
|
||||
Shortcut for
|
||||
|
||||
>>> bot.editReplyMarkup(chat_id=message.chat_id,
|
||||
... message_id=message.message_id,
|
||||
... *args, **kwargs)
|
||||
|
||||
Note:
|
||||
You can only edit messages that the bot sent itself,
|
||||
therefore this method can only be used on the
|
||||
return value of the bot.send_* family of methods.
|
||||
return value of the ``bot.send_*`` family of methods.
|
||||
"""
|
||||
return self.bot.edit_message_caption(
|
||||
return self.bot.edit_message_reply_markup(
|
||||
chat_id=self.chat_id, message_id=self.message_id, *args, **kwargs)
|
||||
|
||||
def parse_entity(self, entity):
|
||||
@@ -502,8 +549,8 @@ class Message(TelegramObject):
|
||||
(That is, you can't just slice ``Message.text`` with the offset and length.)
|
||||
|
||||
Args:
|
||||
entity (MessageEntity): The entity to extract the text from. It must be an entity that
|
||||
belongs to this message.
|
||||
entity (telegram.MessageEntity): The entity to extract the text from. It must be an
|
||||
entity that belongs to this message.
|
||||
|
||||
Returns:
|
||||
str: The text of the given entity
|
||||
@@ -529,8 +576,8 @@ class Message(TelegramObject):
|
||||
See ``get_entity_text`` for more info.
|
||||
|
||||
Args:
|
||||
types (Optional[list]): List of ``MessageEntity`` types as strings. If the ``type``
|
||||
attribute of an entity is contained in this list, it will be returned.
|
||||
types (Optional[list]): List of ``telegram.MessageEntity`` types as strings. If the
|
||||
``type`` attribute of an entity is contained in this list, it will be returned.
|
||||
Defaults to a list of all types. All types can be found as constants in
|
||||
:class:`telegram.MessageEntity`.
|
||||
|
||||
|
||||
@@ -16,30 +16,31 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram
|
||||
ReplyKeyboardHide."""
|
||||
|
||||
"""This module contains an object that represents a Telegram ReplyKeyboardRemove."""
|
||||
from telegram import ReplyMarkup
|
||||
from telegram.utils.deprecate import warn_deprecate_obj
|
||||
|
||||
|
||||
class ReplyKeyboardHide(ReplyMarkup):
|
||||
"""This object represents a Telegram ReplyKeyboardHide.
|
||||
class ReplyKeyboardRemove(ReplyMarkup):
|
||||
"""This object represents a Telegram ReplyKeyboardRemove.
|
||||
|
||||
Attributes:
|
||||
hide_keyboard (bool):
|
||||
remove_keyboard (bool): Always True.
|
||||
selective (bool):
|
||||
|
||||
Args:
|
||||
hide_keyboard (bool):
|
||||
selective (Optional[bool]): Use this parameter if you want to remove the keyboard for
|
||||
specific users only. Targets:
|
||||
1) users that are @mentioned in the text of the Message object;
|
||||
2) if the bot's message is a reply (has reply_to_message_id), sender of the
|
||||
original message.
|
||||
**kwargs: Arbitrary keyword arguments.
|
||||
|
||||
Keyword Args:
|
||||
selective (Optional[bool]):
|
||||
"""
|
||||
|
||||
def __init__(self, hide_keyboard=True, selective=False, **kwargs):
|
||||
def __init__(self, selective=False, **kwargs):
|
||||
# Required
|
||||
self.hide_keyboard = bool(hide_keyboard)
|
||||
self.remove_keyboard = True
|
||||
# Optionals
|
||||
self.selective = bool(selective)
|
||||
|
||||
@@ -51,9 +52,19 @@ class ReplyKeyboardHide(ReplyMarkup):
|
||||
bot(telegram.Bot):
|
||||
|
||||
Returns:
|
||||
telegram.ReplyKeyboardHide:
|
||||
telegram.ReplyKeyboardRemove
|
||||
|
||||
"""
|
||||
if not data:
|
||||
return None
|
||||
|
||||
return ReplyKeyboardHide(**data)
|
||||
return ReplyKeyboardRemove(**data)
|
||||
|
||||
|
||||
class ReplyKeyboardHide(object):
|
||||
|
||||
def __new__(cls, hide_keyboard=True, selective=False, **kwargs):
|
||||
warn_deprecate_obj(ReplyKeyboardHide.__name__, ReplyKeyboardRemove.__name__)
|
||||
obj = ReplyKeyboardRemove.__new__(ReplyKeyboardRemove, selective)
|
||||
obj.__init__(selective)
|
||||
return obj
|
||||
+23
-9
@@ -25,23 +25,31 @@ class Update(TelegramObject):
|
||||
"""This object represents a Telegram Update.
|
||||
|
||||
Attributes:
|
||||
update_id (int):
|
||||
message (:class:`telegram.Message`):
|
||||
edited_message (:class:`telegram.Message`):
|
||||
inline_query (:class:`telegram.InlineQuery`):
|
||||
chosen_inline_result (:class:`telegram.ChosenInlineResult`):
|
||||
callback_query (:class:`telegram.CallbackQuery`):
|
||||
update_id (int): The update's unique identifier.
|
||||
message (:class:`telegram.Message`): New incoming message of any kind - text, photo,
|
||||
sticker, etc.
|
||||
edited_message (:class:`telegram.Message`): New version of a message that is known to the
|
||||
bot and was edited
|
||||
inline_query (:class:`telegram.InlineQuery`): New incoming inline query.
|
||||
chosen_inline_result (:class:`telegram.ChosenInlineResult`): The result of an inline query
|
||||
that was chosen by a user and sent to their chat partner.
|
||||
callback_query (:class:`telegram.CallbackQuery`): New incoming callback query.
|
||||
channel_post (Optional[:class:`telegram.Message`]): New incoming channel post of any kind -
|
||||
text, photo, sticker, etc.
|
||||
edited_channel_post (Optional[:class:`telegram.Message`]): New version of a channel post
|
||||
that is known to the bot and was edited.
|
||||
|
||||
Args:
|
||||
update_id (int):
|
||||
**kwargs: Arbitrary keyword arguments.
|
||||
|
||||
Keyword Args:
|
||||
message (Optional[:class:`telegram.Message`]):
|
||||
edited_message (Optional[:class:`telegram.Message`]):
|
||||
inline_query (Optional[:class:`telegram.InlineQuery`]):
|
||||
chosen_inline_result (Optional[:class:`telegram.ChosenInlineResult`])
|
||||
callback_query (Optional[:class:`telegram.CallbackQuery`]):
|
||||
channel_post (Optional[:class:`telegram.Message`]):
|
||||
edited_channel_post (Optional[:class:`telegram.Message`]):
|
||||
**kwargs: Arbitrary keyword arguments.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
@@ -51,6 +59,8 @@ class Update(TelegramObject):
|
||||
inline_query=None,
|
||||
chosen_inline_result=None,
|
||||
callback_query=None,
|
||||
channel_post=None,
|
||||
edited_channel_post=None,
|
||||
**kwargs):
|
||||
# Required
|
||||
self.update_id = int(update_id)
|
||||
@@ -60,6 +70,8 @@ class Update(TelegramObject):
|
||||
self.inline_query = inline_query
|
||||
self.chosen_inline_result = chosen_inline_result
|
||||
self.callback_query = callback_query
|
||||
self.channel_post = channel_post
|
||||
self.edited_channel_post = edited_channel_post
|
||||
|
||||
@staticmethod
|
||||
def de_json(data, bot):
|
||||
@@ -80,5 +92,7 @@ class Update(TelegramObject):
|
||||
data['chosen_inline_result'] = ChosenInlineResult.de_json(
|
||||
data.get('chosen_inline_result'), bot)
|
||||
data['callback_query'] = CallbackQuery.de_json(data.get('callback_query'), bot)
|
||||
data['channel_post'] = Message.de_json(data.get('channel_post'), bot)
|
||||
data['edited_channel_post'] = Message.de_json(data.get('edited_channel_post'), bot)
|
||||
|
||||
return Update(**data)
|
||||
|
||||
@@ -21,11 +21,15 @@
|
||||
import warnings
|
||||
|
||||
|
||||
def warn_deprecate_obj(old, new):
|
||||
warnings.warn('{0} is being deprecated, please use {1} from now on'.format(old, new))
|
||||
|
||||
|
||||
def deprecate(func, old, new):
|
||||
"""Warn users invoking old to switch to the new function."""
|
||||
|
||||
def f(*args, **kwargs):
|
||||
warnings.warn("{0} is being deprecated, please use {1} from now on".format(old, new))
|
||||
warn_deprecate_obj(old, new)
|
||||
return func(*args, **kwargs)
|
||||
|
||||
return f
|
||||
|
||||
@@ -31,8 +31,8 @@ import urllib3
|
||||
from urllib3.connection import HTTPConnection
|
||||
|
||||
from telegram import (InputFile, TelegramError)
|
||||
from telegram.error import Unauthorized, NetworkError, TimedOut, BadRequest, ChatMigrated, \
|
||||
RetryAfter
|
||||
from telegram.error import Unauthorized, InvalidToken, NetworkError, TimedOut, BadRequest, \
|
||||
ChatMigrated, RetryAfter
|
||||
|
||||
logging.getLogger('urllib3').setLevel(logging.WARNING)
|
||||
|
||||
@@ -150,6 +150,8 @@ class Request(object):
|
||||
raise Unauthorized()
|
||||
elif resp.status == 400:
|
||||
raise BadRequest(repr(message))
|
||||
elif resp.status == 404:
|
||||
raise InvalidToken()
|
||||
elif resp.status == 502:
|
||||
raise NetworkError('Bad Gateway')
|
||||
else:
|
||||
|
||||
+1
-1
@@ -17,4 +17,4 @@
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
__version__ = '5.2.0'
|
||||
__version__ = '5.3.0'
|
||||
|
||||
+84
-6
@@ -34,6 +34,9 @@ import telegram
|
||||
from telegram.error import BadRequest
|
||||
from tests.base import BaseTest, timeout
|
||||
|
||||
BASE_TIME = time.time()
|
||||
HIGHSCORE_DELTA = 1450000000
|
||||
|
||||
|
||||
class BotTest(BaseTest, unittest.TestCase):
|
||||
"""This object represents Tests for Telegram Bot."""
|
||||
@@ -227,7 +230,7 @@ class BotTest(BaseTest, unittest.TestCase):
|
||||
bot.getMe()
|
||||
|
||||
def testInvalidSrvResp(self):
|
||||
with self.assertRaisesRegexp(telegram.TelegramError, 'Invalid server response'):
|
||||
with self.assertRaisesRegexp(telegram.error.InvalidToken, 'Invalid token'):
|
||||
# bypass the valid token check
|
||||
newbot_cls = type(
|
||||
'NoTokenValidateBot', (telegram.Bot,), dict(_validate_token=lambda x, y: None))
|
||||
@@ -286,6 +289,16 @@ class BotTest(BaseTest, unittest.TestCase):
|
||||
self.assertEqual(chat_member.status, "administrator")
|
||||
self._testUserEqualsBot(bot)
|
||||
|
||||
@flaky(3, 1)
|
||||
@timeout(10)
|
||||
def test_forward_channel_messgae(self):
|
||||
text = 'test forward message'
|
||||
msg = self._bot.sendMessage(self._channel_id, text)
|
||||
self.assertEqual(text, msg.text)
|
||||
fwdmsg = msg.forward(self._chat_id)
|
||||
self.assertEqual(text, fwdmsg.text)
|
||||
self.assertEqual(fwdmsg.forward_from_message_id, msg.message_id)
|
||||
|
||||
@flaky(3, 1)
|
||||
@timeout(10)
|
||||
def test_get_webhook_info(self):
|
||||
@@ -297,17 +310,16 @@ class BotTest(BaseTest, unittest.TestCase):
|
||||
|
||||
@flaky(3, 1)
|
||||
@timeout(10)
|
||||
def test_set_game_score(self):
|
||||
# We need a game to set the score for
|
||||
def test_set_game_score1(self):
|
||||
# NOTE: numbering of methods assures proper order between test_set_game_scoreX methods
|
||||
game_short_name = 'python_telegram_bot_test_game'
|
||||
game = self._bot.sendGame(game_short_name=game_short_name, chat_id=self._chat_id)
|
||||
|
||||
message = self._bot.set_game_score(
|
||||
user_id=self._chat_id,
|
||||
score=int(time.time() - 1450000000),
|
||||
score=int(BASE_TIME) - HIGHSCORE_DELTA,
|
||||
chat_id=game.chat_id,
|
||||
message_id=game.message_id,
|
||||
edit_message=True)
|
||||
message_id=game.message_id)
|
||||
|
||||
self.assertTrue(self.is_json(game.to_json()))
|
||||
self.assertEqual(message.game.description, game.game.description)
|
||||
@@ -315,6 +327,72 @@ class BotTest(BaseTest, unittest.TestCase):
|
||||
self.assertEqual(message.game.photo[0].file_size, game.game.photo[0].file_size)
|
||||
self.assertNotEqual(message.game.text, game.game.text)
|
||||
|
||||
@flaky(3, 1)
|
||||
@timeout(10)
|
||||
def test_set_game_score2(self):
|
||||
# NOTE: numbering of methods assures proper order between test_set_game_scoreX methods
|
||||
game_short_name = 'python_telegram_bot_test_game'
|
||||
game = self._bot.sendGame(game_short_name=game_short_name, chat_id=self._chat_id)
|
||||
|
||||
score = int(BASE_TIME) - HIGHSCORE_DELTA + 1
|
||||
|
||||
message = self._bot.set_game_score(
|
||||
user_id=self._chat_id,
|
||||
score=score,
|
||||
chat_id=game.chat_id,
|
||||
message_id=game.message_id,
|
||||
disable_edit_message=True)
|
||||
|
||||
self.assertTrue(self.is_json(game.to_json()))
|
||||
self.assertEqual(message.game.description, game.game.description)
|
||||
self.assertEqual(message.game.animation.file_id, game.game.animation.file_id)
|
||||
self.assertEqual(message.game.photo[0].file_size, game.game.photo[0].file_size)
|
||||
self.assertEqual(message.game.text, game.game.text)
|
||||
|
||||
@flaky(3, 1)
|
||||
@timeout(10)
|
||||
def test_set_game_score3(self):
|
||||
# NOTE: numbering of methods assures proper order between test_set_game_scoreX methods
|
||||
game_short_name = 'python_telegram_bot_test_game'
|
||||
game = self._bot.sendGame(game_short_name=game_short_name, chat_id=self._chat_id)
|
||||
|
||||
score = int(BASE_TIME) - HIGHSCORE_DELTA - 1
|
||||
|
||||
with self.assertRaises(BadRequest) as cm:
|
||||
self._bot.set_game_score(
|
||||
user_id=self._chat_id,
|
||||
score=score,
|
||||
chat_id=game.chat_id,
|
||||
message_id=game.message_id)
|
||||
|
||||
self.assertTrue('BOT_SCORE_NOT_MODIFIED' in cm.exception.message)
|
||||
|
||||
@flaky(3, 1)
|
||||
@timeout(10)
|
||||
def test_set_game_score4(self):
|
||||
# NOTE: numbering of methods assures proper order between test_set_game_scoreX methods
|
||||
game_short_name = 'python_telegram_bot_test_game'
|
||||
game = self._bot.sendGame(game_short_name=game_short_name, chat_id=self._chat_id)
|
||||
|
||||
score = int(BASE_TIME) - HIGHSCORE_DELTA - 2
|
||||
|
||||
message = self._bot.set_game_score(
|
||||
user_id=self._chat_id,
|
||||
score=score,
|
||||
chat_id=game.chat_id,
|
||||
message_id=game.message_id,
|
||||
force=True)
|
||||
|
||||
self.assertTrue(self.is_json(game.to_json()))
|
||||
self.assertEqual(message.game.description, game.game.description)
|
||||
self.assertEqual(message.game.animation.file_id, game.game.animation.file_id)
|
||||
self.assertEqual(message.game.photo[0].file_size, game.game.photo[0].file_size)
|
||||
|
||||
# For some reason the returned message does not contain the updated score. need to fetch
|
||||
# the game again...
|
||||
game2 = self._bot.sendGame(game_short_name=game_short_name, chat_id=self._chat_id)
|
||||
self.assertIn(str(score), game2.game.text)
|
||||
|
||||
@flaky(3, 1)
|
||||
@timeout(10)
|
||||
def test_set_game_score_too_low_score(self):
|
||||
|
||||
+11
-5
@@ -47,20 +47,26 @@ class ConstantsTest(BaseTest, unittest.TestCase):
|
||||
@flaky(3, 1)
|
||||
@timeout(10)
|
||||
def testMaxCaptionLength(self):
|
||||
self._bot.sendPhoto(
|
||||
good_caption = 'a' * telegram.constants.MAX_CAPTION_LENGTH
|
||||
good_msg = self._bot.sendPhoto(
|
||||
photo=open('tests/data/telegram.png', 'rb'),
|
||||
caption='a' * telegram.constants.MAX_CAPTION_LENGTH,
|
||||
caption=good_caption,
|
||||
chat_id=self._chat_id)
|
||||
self.assertEqual(good_msg.caption, good_caption)
|
||||
|
||||
bad_caption = good_caption + 'Z'
|
||||
try:
|
||||
self._bot.sendPhoto(
|
||||
bad_msg = self._bot.sendPhoto(
|
||||
photo=open('tests/data/telegram.png', 'rb'),
|
||||
caption='a' * (telegram.constants.MAX_CAPTION_LENGTH + 1),
|
||||
chat_id=self._chat_id)
|
||||
except BadRequest as e:
|
||||
# This used to be the way long caption was handled before Oct? Nov? 2016
|
||||
err = str(e)
|
||||
|
||||
self.assertTrue("TOO_LONG" in err) # BadRequest: 'MEDIA_CAPTION_TOO_LONG'
|
||||
self.assertTrue("TOO_LONG" in err) # BadRequest: 'MEDIA_CAPTION_TOO_LONG'
|
||||
else:
|
||||
self.assertNotEqual(bad_msg.caption, bad_caption)
|
||||
self.assertEqual(len(bad_msg.caption), telegram.constants.MAX_CAPTION_LENGTH)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -51,6 +51,13 @@ class FiltersTest(BaseTest, unittest.TestCase):
|
||||
self.message.text = '/test'
|
||||
self.assertTrue(Filters.command(self.message))
|
||||
|
||||
def test_filters_reply(self):
|
||||
another_message = Message(1, User(1, "TestOther"), datetime.now(), Chat(0, 'private'))
|
||||
self.message.text = 'test'
|
||||
self.assertFalse(Filters.reply(self.message))
|
||||
self.message.reply_to_message = another_message
|
||||
self.assertTrue(Filters.reply(self.message))
|
||||
|
||||
def test_filters_audio(self):
|
||||
self.message.audio = 'test'
|
||||
self.assertTrue(Filters.audio(self.message))
|
||||
|
||||
@@ -23,6 +23,9 @@ This module contains an object that represents Tests for JobQueue
|
||||
import logging
|
||||
import sys
|
||||
import unittest
|
||||
import datetime
|
||||
import time
|
||||
from math import ceil
|
||||
from time import sleep
|
||||
|
||||
from tests.test_updater import MockBot
|
||||
@@ -53,11 +56,15 @@ class JobQueueTest(BaseTest, unittest.TestCase):
|
||||
self.jq = JobQueue(MockBot('jobqueue_test'))
|
||||
self.jq.start()
|
||||
self.result = 0
|
||||
self.job_time = 0
|
||||
|
||||
def tearDown(self):
|
||||
if self.jq is not None:
|
||||
self.jq.stop()
|
||||
|
||||
def getSeconds(self):
|
||||
return int(ceil(time.time()))
|
||||
|
||||
def job1(self, bot, job):
|
||||
self.result += 1
|
||||
|
||||
@@ -71,6 +78,9 @@ class JobQueueTest(BaseTest, unittest.TestCase):
|
||||
def job4(self, bot, job):
|
||||
self.result += job.context
|
||||
|
||||
def job5(self, bot, job):
|
||||
self.job_time = self.getSeconds()
|
||||
|
||||
def test_basic(self):
|
||||
self.jq.put(Job(self.job1, 0.1))
|
||||
sleep(1.5)
|
||||
@@ -169,6 +179,25 @@ class JobQueueTest(BaseTest, unittest.TestCase):
|
||||
finally:
|
||||
u.stop()
|
||||
|
||||
def test_time_unit_int(self):
|
||||
# Testing seconds in int
|
||||
seconds_interval = 5
|
||||
expected_time = self.getSeconds() + seconds_interval
|
||||
|
||||
self.jq.put(Job(self.job5, seconds_interval, repeat=False))
|
||||
sleep(6)
|
||||
self.assertEqual(self.job_time, expected_time)
|
||||
|
||||
def test_time_unit_dt_time(self):
|
||||
# Testing seconds, minutes and hours as datetime.timedelta object
|
||||
# This is sufficient to test that it actually works.
|
||||
interval = datetime.timedelta(seconds=5)
|
||||
expected_time = self.getSeconds() + interval.total_seconds()
|
||||
|
||||
self.jq.put(Job(self.job5, interval, repeat=False))
|
||||
sleep(6)
|
||||
self.assertEqual(self.job_time, expected_time)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents Tests for Telegram ReplyKeyboardHide"""
|
||||
"""This module contains an object that represents Tests for Telegram ReplyKeyboardRemove"""
|
||||
|
||||
import sys
|
||||
import unittest
|
||||
@@ -28,48 +28,48 @@ import telegram
|
||||
from tests.base import BaseTest
|
||||
|
||||
|
||||
class ReplyKeyboardHideTest(BaseTest, unittest.TestCase):
|
||||
"""This object represents Tests for Telegram ReplyKeyboardHide."""
|
||||
class ReplyKeyboardRemoveTest(BaseTest, unittest.TestCase):
|
||||
"""This object represents Tests for Telegram ReplyKeyboardRemove."""
|
||||
|
||||
def setUp(self):
|
||||
self.hide_keyboard = True
|
||||
self.remove_keyboard = True
|
||||
self.selective = True
|
||||
|
||||
self.json_dict = {
|
||||
'hide_keyboard': self.hide_keyboard,
|
||||
'remove_keyboard': self.remove_keyboard,
|
||||
'selective': self.selective,
|
||||
}
|
||||
|
||||
def test_send_message_with_reply_keyboard_hide(self):
|
||||
def test_send_message_with_reply_keyboard_remove(self):
|
||||
message = self._bot.sendMessage(
|
||||
self._chat_id,
|
||||
'Моё судно на воздушной подушке полно угрей',
|
||||
reply_markup=telegram.ReplyKeyboardHide.de_json(self.json_dict, self._bot))
|
||||
reply_markup=telegram.ReplyKeyboardRemove.de_json(self.json_dict, self._bot))
|
||||
|
||||
self.assertTrue(self.is_json(message.to_json()))
|
||||
self.assertEqual(message.text, u'Моё судно на воздушной подушке полно угрей')
|
||||
|
||||
def test_reply_keyboard_hide_de_json(self):
|
||||
reply_keyboard_hide = telegram.ReplyKeyboardHide.de_json(self.json_dict, self._bot)
|
||||
def test_reply_keyboard_remove_de_json(self):
|
||||
reply_keyboard_remove = telegram.ReplyKeyboardRemove.de_json(self.json_dict, self._bot)
|
||||
|
||||
self.assertEqual(reply_keyboard_hide.hide_keyboard, self.hide_keyboard)
|
||||
self.assertEqual(reply_keyboard_hide.selective, self.selective)
|
||||
self.assertEqual(reply_keyboard_remove.remove_keyboard, self.remove_keyboard)
|
||||
self.assertEqual(reply_keyboard_remove.selective, self.selective)
|
||||
|
||||
def test_reply_keyboard_hide_de_json_empty(self):
|
||||
reply_keyboard_hide = telegram.ReplyKeyboardHide.de_json(None, self._bot)
|
||||
def test_reply_keyboard_remove_de_json_empty(self):
|
||||
reply_keyboard_remove = telegram.ReplyKeyboardRemove.de_json(None, self._bot)
|
||||
|
||||
self.assertFalse(reply_keyboard_hide)
|
||||
self.assertFalse(reply_keyboard_remove)
|
||||
|
||||
def test_reply_keyboard_hide_to_json(self):
|
||||
reply_keyboard_hide = telegram.ReplyKeyboardHide.de_json(self.json_dict, self._bot)
|
||||
def test_reply_keyboard_remove_to_json(self):
|
||||
reply_keyboard_remove = telegram.ReplyKeyboardRemove.de_json(self.json_dict, self._bot)
|
||||
|
||||
self.assertTrue(self.is_json(reply_keyboard_hide.to_json()))
|
||||
self.assertTrue(self.is_json(reply_keyboard_remove.to_json()))
|
||||
|
||||
def test_reply_keyboard_hide_to_dict(self):
|
||||
reply_keyboard_hide = telegram.ReplyKeyboardHide.de_json(self.json_dict, self._bot)
|
||||
def test_reply_keyboard_remove_to_dict(self):
|
||||
reply_keyboard_remove = telegram.ReplyKeyboardRemove.de_json(self.json_dict, self._bot)
|
||||
|
||||
self.assertEqual(reply_keyboard_hide['hide_keyboard'], self.hide_keyboard)
|
||||
self.assertEqual(reply_keyboard_hide['selective'], self.selective)
|
||||
self.assertEqual(reply_keyboard_remove['remove_keyboard'], self.remove_keyboard)
|
||||
self.assertEqual(reply_keyboard_remove['selective'], self.selective)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
Reference in New Issue
Block a user