mirror of
https://github.com/python-telegram-bot/python-telegram-bot.git
synced 2026-06-23 09:45:30 +00:00
Compare commits
92 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2786252a51 | |||
| 3f30f74024 | |||
| 79fc3be9cd | |||
| 71c73bdc74 | |||
| 761547e71d | |||
| 10bdf8212c | |||
| 45936c9982 | |||
| fae1896232 | |||
| 2518ddac22 | |||
| 61fe438a8b | |||
| 960862ccb1 | |||
| 4e5f4582dd | |||
| 225bc24c2a | |||
| a5f9aa3171 | |||
| 78088f4f6a | |||
| 59fa717023 | |||
| 31cab0d1b4 | |||
| 7fafaa1ea3 | |||
| e367b8519d | |||
| b610316667 | |||
| 39832d2f6b | |||
| 5408c23e33 | |||
| 62dd3a33e6 | |||
| 3754cdafb2 | |||
| 305ff93018 | |||
| 29e0cc64e9 | |||
| a5671a8fb1 | |||
| f99b2f8f3b | |||
| c626044a30 | |||
| a68cf8d464 | |||
| de96cc87ea | |||
| ca5e3146c6 | |||
| 53a574bbbb | |||
| 5b8efe0c14 | |||
| d07a1c3f67 | |||
| 32a78722ae | |||
| 04feeeff55 | |||
| a1495956aa | |||
| 8dc10fc7b2 | |||
| 7ad92dcc65 | |||
| d1ddfaddf0 | |||
| b7c7612b3f | |||
| ade89772f4 | |||
| 67b98e3190 | |||
| e672625a41 | |||
| 8cab735342 | |||
| bfb4c63d60 | |||
| 01a5a1c5b3 | |||
| 1db1b76a7c | |||
| 976f34082f | |||
| 6b7788570c | |||
| 1f9d3163dd | |||
| 837e9d2964 | |||
| fab97df58a | |||
| d70fc48e94 | |||
| 36192912c2 | |||
| 34748ec228 | |||
| d5567cd9cd | |||
| 2463b4b9c8 | |||
| 7cf5009517 | |||
| 9b74625d4a | |||
| 4180c069b3 | |||
| 3a0f219783 | |||
| 3c889655c1 | |||
| c2b8c4bf95 | |||
| 8234321a20 | |||
| 5e2d96b47d | |||
| 551f6c556c | |||
| ae17eb3272 | |||
| 358dd795c7 | |||
| 151a441af7 | |||
| 1f67623615 | |||
| 8737b5de63 | |||
| f3b8a3a5e9 | |||
| 9e9309eb90 | |||
| e8a34d8eef | |||
| 34c62a633b | |||
| 868d9217bc | |||
| f7ede4baea | |||
| c3e07b1056 | |||
| 79bdfe4c5d | |||
| 46657afa95 | |||
| 79e065a730 | |||
| 9928a1eefc | |||
| 0e2c3666c0 | |||
| a996e8873f | |||
| 3244417f61 | |||
| 61596400e1 | |||
| be0f5bc519 | |||
| 921fbae2f3 | |||
| 2161681131 | |||
| 71e74da0a2 |
@@ -184,8 +184,8 @@ break the API classes. For example:
|
||||
.. code-block:: python
|
||||
|
||||
# GOOD
|
||||
def __init__(self, id, name, **kwargs):
|
||||
self.last_name = kwargs.get('last_name', '')
|
||||
def __init__(self, id, name, last_name='', **kwargs):
|
||||
self.last_name = last_name
|
||||
|
||||
# BAD
|
||||
def __init__(self, id, name, last_name=''):
|
||||
|
||||
@@ -68,3 +68,6 @@ telegram.mp4
|
||||
telegram.ogg
|
||||
telegram.png
|
||||
telegram.webp
|
||||
|
||||
# original files from merges
|
||||
*.orig
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
- repo: git://github.com/pre-commit/mirrors-yapf
|
||||
sha: v0.11.0
|
||||
- repo: git://github.com/python-telegram-bot/mirrors-yapf
|
||||
sha: v0.12.2
|
||||
hooks:
|
||||
- id: yapf
|
||||
files: ^(telegram|tests)/.*\.py$
|
||||
|
||||
+4
-1
@@ -6,6 +6,9 @@ python:
|
||||
- "3.5"
|
||||
- "pypy"
|
||||
- "pypy3"
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
install:
|
||||
- pip install coveralls
|
||||
- pip install -r requirements.txt
|
||||
@@ -13,6 +16,6 @@ install:
|
||||
- if [[ $TRAVIS_PYTHON_VERSION != 'pypy'* ]]; then pip install ujson; fi
|
||||
script:
|
||||
- nosetests -v --with-flaky --no-flaky-report --with-coverage --cover-package=telegram/
|
||||
- if [ $TRAVIS_PYTHON_VERSION != 3.3 ] && [ $TRAVIS_PYTHON_VERSION != pypy3 ]; then pre-commit run --all-files; fi
|
||||
- if [[ $TRAVIS_PYTHON_VERSION == 3.5 ]]; then pre-commit run --all-files; fi
|
||||
after_success:
|
||||
coveralls
|
||||
|
||||
@@ -21,11 +21,13 @@ The following wonderful people contributed directly or indirectly to this projec
|
||||
- `jlmadurga <https://github.com/jlmadurga>`_
|
||||
- `Li-aung Yip <https://github.com/LiaungYip>`_
|
||||
- `macrojames <https://github.com/macrojames>`_
|
||||
- `Michael Elovskikh <https://github.com/wronglink>`_
|
||||
- `naveenvhegde <https://github.com/naveenvhegde>`_
|
||||
- `njittam <https://github.com/njittam>`_
|
||||
- `Noam Meltzer <https://github.com/tsnoam>`_
|
||||
- `Oleg Shlyazhko <https://github.com/ollmer>`_
|
||||
- `overquota <https://github.com/overquota>`_
|
||||
- `Patrick Hofmann <https://github.com/PH89>`_
|
||||
- `Rahiel Kasim <https://github.com/rahiel>`_
|
||||
- `Shelomentsev D <https://github.com/shelomentsevd>`_
|
||||
- `sooyhwang <https://github.com/sooyhwang>`_
|
||||
|
||||
+10
@@ -2,6 +2,16 @@
|
||||
Changes
|
||||
=======
|
||||
|
||||
**2016-10-25**
|
||||
|
||||
*Released 5.2*
|
||||
|
||||
- Implement API changes of October 3rd (games update)
|
||||
- Add ``Message.edit_*`` methods
|
||||
- Filters for the ``MessageHandler`` can now be combined using bitwise operators (``& and |``)
|
||||
- Add a way to save user- and chat-related data temporarily
|
||||
- Other bugfixes and improvements
|
||||
|
||||
**2016-09-24**
|
||||
|
||||
*Released 5.1*
|
||||
|
||||
+5
-5
@@ -16,7 +16,7 @@ We have made you a wrapper you can't refuse
|
||||
:alt: Supported python versions
|
||||
|
||||
.. image:: https://img.shields.io/badge/docs-latest-af1a97.svg
|
||||
:target: https://pythonhosted.org/python-telegram-bot/
|
||||
:target: https://python-telegram-bot.readthedocs.io/
|
||||
:alt: Documentation Status
|
||||
|
||||
.. image:: https://img.shields.io/pypi/l/python-telegram-bot.svg
|
||||
@@ -37,7 +37,7 @@ We have made you a wrapper you can't refuse
|
||||
|
||||
.. image:: http://isitmaintained.com/badge/resolution/python-telegram-bot/python-telegram-bot.svg
|
||||
:target: http://isitmaintained.com/project/python-telegram-bot/python-telegram-bot
|
||||
:alt: Average time to resolve an issue
|
||||
:alt: Median time to resolve an issue
|
||||
|
||||
.. image:: https://img.shields.io/badge/Telegram-Group-blue.svg
|
||||
:target: https://telegram.me/pythontelegrambotgroup
|
||||
@@ -84,7 +84,7 @@ make the development of bots easy and straightforward. These classes are contain
|
||||
Telegram API support
|
||||
====================
|
||||
|
||||
As of **28. May 2016**, all types and methods of the Telegram Bot API are supported.
|
||||
As of **3. Oct 2016**, all types and methods of the Telegram Bot API are supported.
|
||||
|
||||
==========
|
||||
Installing
|
||||
@@ -116,7 +116,7 @@ Our Wiki contains a lot of resources to get you started with ``python-telegram-b
|
||||
Other references:
|
||||
|
||||
- `Telegram API documentation <https://core.telegram.org/bots/api>`_
|
||||
- `python-telegram-bot documentation <https://pythonhosted.org/python-telegram-bot/>`_
|
||||
- `python-telegram-bot documentation <https://python-telegram-bot.readthedocs.io/>`_
|
||||
|
||||
-------------------
|
||||
Learning by example
|
||||
@@ -162,7 +162,7 @@ If you want DEBUG logs instead:
|
||||
Documentation
|
||||
=============
|
||||
|
||||
``python-telegram-bot``'s documentation lives at `pythonhosted.org <https://pythonhosted.org/python-telegram-bot/>`_.
|
||||
``python-telegram-bot``'s documentation lives at `readthedocs.io <https://python-telegram-bot.readthedocs.io/>`_.
|
||||
|
||||
============
|
||||
Getting help
|
||||
|
||||
+3
-3
@@ -15,7 +15,7 @@
|
||||
import sys
|
||||
import os
|
||||
import shlex
|
||||
import telegram
|
||||
# import telegram
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
@@ -59,9 +59,9 @@ author = u'Leandro Toledo'
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = telegram.__version__[:3]
|
||||
version = '5.2' # telegram.__version__[:3]
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = telegram.__version__
|
||||
release = '5.2.0' # telegram.__version__
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
telegram.ext.filters module
|
||||
===========================
|
||||
|
||||
.. automodule:: telegram.ext.filters
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
@@ -15,6 +15,7 @@ Submodules
|
||||
telegram.ext.commandhandler
|
||||
telegram.ext.inlinequeryhandler
|
||||
telegram.ext.messagehandler
|
||||
telegram.ext.filters
|
||||
telegram.ext.regexhandler
|
||||
telegram.ext.stringcommandhandler
|
||||
telegram.ext.stringregexhandler
|
||||
|
||||
+5
-2
@@ -8,10 +8,13 @@ All examples are licensed under the [CC0 License](https://github.com/python-tele
|
||||
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://pythonhosted.org/python-telegram-bot/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).
|
||||
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://pythonhosted.org/python-telegram-bot/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.
|
||||
|
||||
### [`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`
|
||||
|
||||
### [`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.
|
||||
|
||||
@@ -127,13 +127,13 @@ def main():
|
||||
states={
|
||||
GENDER: [RegexHandler('^(Boy|Girl|Other)$', gender)],
|
||||
|
||||
PHOTO: [MessageHandler([Filters.photo], photo),
|
||||
PHOTO: [MessageHandler(Filters.photo, photo),
|
||||
CommandHandler('skip', skip_photo)],
|
||||
|
||||
LOCATION: [MessageHandler([Filters.location], location),
|
||||
LOCATION: [MessageHandler(Filters.location, location),
|
||||
CommandHandler('skip', skip_location)],
|
||||
|
||||
BIO: [MessageHandler([Filters.text], bio)]
|
||||
BIO: [MessageHandler(Filters.text, bio)]
|
||||
},
|
||||
|
||||
fallbacks=[CommandHandler('cancel', cancel)]
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Simple Bot to reply to Telegram messages
|
||||
# This program is dedicated to the public domain under the CC0 license.
|
||||
"""
|
||||
This Bot uses the Updater class to handle the bot.
|
||||
|
||||
First, a few callback functions are defined. Then, those functions are passed to
|
||||
the Dispatcher and registered at their respective places.
|
||||
Then, the bot is started and runs until we press Ctrl-C on the command line.
|
||||
|
||||
Usage:
|
||||
Example of a bot-user conversation using ConversationHandler.
|
||||
Send /start to initiate the conversation.
|
||||
Press Ctrl-C on the command line or send a signal to the process to stop the
|
||||
bot.
|
||||
"""
|
||||
|
||||
from telegram import ReplyKeyboardMarkup
|
||||
from telegram.ext import (Updater, CommandHandler, MessageHandler, Filters, RegexHandler,
|
||||
ConversationHandler)
|
||||
|
||||
import logging
|
||||
|
||||
# Enable logging
|
||||
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
||||
level=logging.INFO)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
CHOOSING, TYPING_REPLY, TYPING_CHOICE = range(3)
|
||||
|
||||
reply_keyboard = [['Age', 'Favourite colour'],
|
||||
['Number of siblings', 'Something else...'],
|
||||
['Done']]
|
||||
markup = ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True)
|
||||
|
||||
|
||||
def facts_to_str(user_data):
|
||||
facts = list()
|
||||
|
||||
for key, value in user_data.items():
|
||||
facts.append('%s - %s' % (key, value))
|
||||
|
||||
return "\n".join(facts).join(['\n', '\n'])
|
||||
|
||||
|
||||
def start(bot, update):
|
||||
update.message.reply_text(
|
||||
"Hi! My name is Doctor Botter. I will hold a more complex conversation with you. "
|
||||
"Why don't you tell me something about yourself?",
|
||||
reply_markup=markup)
|
||||
|
||||
return CHOOSING
|
||||
|
||||
|
||||
def regular_choice(bot, update, user_data):
|
||||
text = update.message.text
|
||||
user_data['choice'] = text
|
||||
update.message.reply_text('Your %s? Yes, I would love to hear about that!' % text.lower())
|
||||
|
||||
return TYPING_REPLY
|
||||
|
||||
|
||||
def custom_choice(bot, update):
|
||||
update.message.reply_text('Alright, please send me the category first, '
|
||||
'for example "Most impressive skill"')
|
||||
|
||||
return TYPING_CHOICE
|
||||
|
||||
|
||||
def received_information(bot, update, user_data):
|
||||
text = update.message.text
|
||||
category = user_data['choice']
|
||||
user_data[category] = text
|
||||
del user_data['choice']
|
||||
|
||||
update.message.reply_text("Neat! Just so you know, this is what you already told me:"
|
||||
"%s"
|
||||
"You can tell me more, or change your opinion on something."
|
||||
% facts_to_str(user_data),
|
||||
reply_markup=markup)
|
||||
|
||||
return CHOOSING
|
||||
|
||||
|
||||
def done(bot, update, user_data):
|
||||
if 'choice' in user_data:
|
||||
del user_data['choice']
|
||||
|
||||
update.message.reply_text("I learned these facts about you:"
|
||||
"%s"
|
||||
"Until next time!" % facts_to_str(user_data))
|
||||
|
||||
user_data.clear()
|
||||
return ConversationHandler.END
|
||||
|
||||
|
||||
def error(bot, update, error):
|
||||
logger.warn('Update "%s" caused error "%s"' % (update, error))
|
||||
|
||||
|
||||
def main():
|
||||
# Create the Updater and pass it your bot's token.
|
||||
updater = Updater("TOKEN")
|
||||
|
||||
# Get the dispatcher to register handlers
|
||||
dp = updater.dispatcher
|
||||
|
||||
# Add conversation handler with the states GENDER, PHOTO, LOCATION and BIO
|
||||
conv_handler = ConversationHandler(
|
||||
entry_points=[CommandHandler('start', start)],
|
||||
|
||||
states={
|
||||
CHOOSING: [RegexHandler('^(Age|Favourite colour|Number of siblings)$',
|
||||
regular_choice,
|
||||
pass_user_data=True),
|
||||
RegexHandler('^Something else...$',
|
||||
custom_choice),
|
||||
],
|
||||
|
||||
TYPING_CHOICE: [MessageHandler(Filters.text,
|
||||
regular_choice,
|
||||
pass_user_data=True),
|
||||
],
|
||||
|
||||
TYPING_REPLY: [MessageHandler(Filters.text,
|
||||
received_information,
|
||||
pass_user_data=True),
|
||||
],
|
||||
},
|
||||
|
||||
fallbacks=[RegexHandler('^Done$', done, pass_user_data=True)]
|
||||
)
|
||||
|
||||
dp.add_handler(conv_handler)
|
||||
|
||||
# log all errors
|
||||
dp.add_error_handler(error)
|
||||
|
||||
# Start the Bot
|
||||
updater.start_polling()
|
||||
|
||||
# Run the bot until the you presses Ctrl-C or the process receives SIGINT,
|
||||
# SIGTERM or SIGABRT. This should be used most of the time, since
|
||||
# start_polling() is non-blocking and will stop the bot gracefully.
|
||||
updater.idle()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -56,7 +56,7 @@ def main():
|
||||
dp.add_handler(CommandHandler("help", help))
|
||||
|
||||
# on noncommand i.e message - echo the message on Telegram
|
||||
dp.add_handler(MessageHandler([Filters.text], echo))
|
||||
dp.add_handler(MessageHandler(Filters.text, echo))
|
||||
|
||||
# log all errors
|
||||
dp.add_error_handler(error)
|
||||
|
||||
+26
-19
@@ -46,6 +46,8 @@ from .file import File
|
||||
from .emoji import Emoji
|
||||
from .parsemode import ParseMode
|
||||
from .messageentity import MessageEntity
|
||||
from .animation import Animation
|
||||
from .game import Game
|
||||
from .message import Message
|
||||
from .inputmessagecontent import InputMessageContent
|
||||
from .callbackquery import CallbackQuery
|
||||
@@ -73,10 +75,13 @@ from .inlinequeryresultphoto import InlineQueryResultPhoto
|
||||
from .inlinequeryresultvenue import InlineQueryResultVenue
|
||||
from .inlinequeryresultvideo import InlineQueryResultVideo
|
||||
from .inlinequeryresultvoice import InlineQueryResultVoice
|
||||
from .inlinequeryresultgame import InlineQueryResultGame
|
||||
from .inputtextmessagecontent import InputTextMessageContent
|
||||
from .inputlocationmessagecontent import InputLocationMessageContent
|
||||
from .inputvenuemessagecontent import InputVenueMessageContent
|
||||
from .inputcontactmessagecontent import InputContactMessageContent
|
||||
from .webhookinfo import WebhookInfo
|
||||
from .gamehighscore import GameHighScore
|
||||
from .update import Update
|
||||
from .bot import Bot
|
||||
from .constants import (MAX_MESSAGE_LENGTH, MAX_CAPTION_LENGTH, SUPPORTED_WEBHOOK_PORTS,
|
||||
@@ -87,22 +92,24 @@ from .version import __version__ # flake8: noqa
|
||||
|
||||
__author__ = 'devs@python-telegram-bot.org'
|
||||
|
||||
__all__ = ['Audio', 'Bot', 'Chat', 'ChatMember', 'ChatAction', 'ChosenInlineResult',
|
||||
'CallbackQuery', 'Contact', 'Document', 'Emoji', 'File', 'ForceReply',
|
||||
'InlineKeyboardButton', 'InlineKeyboardMarkup', 'InlineQuery', 'InlineQueryResult',
|
||||
'InlineQueryResult', 'InlineQueryResultArticle', 'InlineQueryResultAudio',
|
||||
'InlineQueryResultCachedAudio', 'InlineQueryResultCachedDocument',
|
||||
'InlineQueryResultCachedGif', 'InlineQueryResultCachedMpeg4Gif',
|
||||
'InlineQueryResultCachedPhoto', 'InlineQueryResultCachedSticker',
|
||||
'InlineQueryResultCachedVideo', 'InlineQueryResultCachedVoice',
|
||||
'InlineQueryResultContact', 'InlineQueryResultDocument', 'InlineQueryResultGif',
|
||||
'InlineQueryResultLocation', 'InlineQueryResultMpeg4Gif', 'InlineQueryResultPhoto',
|
||||
'InlineQueryResultVenue', 'InlineQueryResultVideo', 'InlineQueryResultVoice',
|
||||
'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',
|
||||
'MAX_FILESIZE_DOWNLOAD', 'MAX_FILESIZE_UPLOAD', 'MAX_MESSAGES_PER_SECOND_PER_CHAT',
|
||||
'MAX_MESSAGES_PER_SECOND', 'MAX_MESSAGES_PER_MINUTE_PER_GROUP']
|
||||
__all__ = [
|
||||
'Audio', 'Bot', 'Chat', 'ChatMember', 'ChatAction', 'ChosenInlineResult', 'CallbackQuery',
|
||||
'Contact', 'Document', 'Emoji', 'File', 'ForceReply', 'InlineKeyboardButton',
|
||||
'InlineKeyboardMarkup', 'InlineQuery', 'InlineQueryResult', 'InlineQueryResult',
|
||||
'InlineQueryResultArticle', 'InlineQueryResultAudio', 'InlineQueryResultCachedAudio',
|
||||
'InlineQueryResultCachedDocument', 'InlineQueryResultCachedGif',
|
||||
'InlineQueryResultCachedMpeg4Gif', 'InlineQueryResultCachedPhoto',
|
||||
'InlineQueryResultCachedSticker', 'InlineQueryResultCachedVideo',
|
||||
'InlineQueryResultCachedVoice', 'InlineQueryResultContact', 'InlineQueryResultDocument',
|
||||
'InlineQueryResultGif', 'InlineQueryResultLocation', 'InlineQueryResultMpeg4Gif',
|
||||
'InlineQueryResultPhoto', 'InlineQueryResultVenue', 'InlineQueryResultVideo',
|
||||
'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',
|
||||
'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'
|
||||
]
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2016
|
||||
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram Animation."""
|
||||
from telegram import PhotoSize
|
||||
from telegram import TelegramObject
|
||||
|
||||
|
||||
class Animation(TelegramObject):
|
||||
"""This object represents a Telegram Animation.
|
||||
|
||||
Attributes:
|
||||
file_id (str): Unique file identifier.
|
||||
|
||||
Keyword Args:
|
||||
thumb (Optional[:class:`telegram.PhotoSize`]): Animation thumbnail as defined by sender.
|
||||
file_name (Optional[str]): Original animation filename as defined by sender.
|
||||
mime_type (Optional[str]): MIME type of the file as defined by sender.
|
||||
file_size (Optional[int]): File size.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, file_id, **kwargs):
|
||||
self.file_id = file_id
|
||||
self.thumb = kwargs.get('thumb')
|
||||
self.file_name = kwargs.get('file_name')
|
||||
self.mime_type = kwargs.get('mime_type')
|
||||
self.file_size = kwargs.get('file_size')
|
||||
|
||||
@staticmethod
|
||||
def de_json(data, bot):
|
||||
"""
|
||||
Args:
|
||||
data (dict):
|
||||
bot (telegram.Bot):
|
||||
|
||||
Returns:
|
||||
telegram.Game:
|
||||
"""
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data['thumb'] = PhotoSize.de_json(data.get('thumb'), bot)
|
||||
|
||||
return Animation(**data)
|
||||
+15
-9
@@ -16,7 +16,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains a object that represents a Telegram Audio."""
|
||||
"""This module contains an object that represents a Telegram Audio."""
|
||||
|
||||
from telegram import TelegramObject
|
||||
|
||||
@@ -35,24 +35,30 @@ class Audio(TelegramObject):
|
||||
Args:
|
||||
file_id (str):
|
||||
duration (int):
|
||||
**kwargs: Arbitrary keyword arguments.
|
||||
|
||||
Keyword Args:
|
||||
performer (Optional[str]):
|
||||
title (Optional[str]):
|
||||
mime_type (Optional[str]):
|
||||
file_size (Optional[int]):
|
||||
**kwargs: Arbitrary keyword arguments.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, file_id, duration, **kwargs):
|
||||
def __init__(self,
|
||||
file_id,
|
||||
duration,
|
||||
performer='',
|
||||
title='',
|
||||
mime_type='',
|
||||
file_size=0,
|
||||
**kwargs):
|
||||
# Required
|
||||
self.file_id = str(file_id)
|
||||
self.duration = int(duration)
|
||||
# Optionals
|
||||
self.performer = kwargs.get('performer', '')
|
||||
self.title = kwargs.get('title', '')
|
||||
self.mime_type = str(kwargs.get('mime_type', ''))
|
||||
self.file_size = int(kwargs.get('file_size', 0))
|
||||
self.performer = performer
|
||||
self.title = title
|
||||
self.mime_type = str(mime_type)
|
||||
self.file_size = int(file_size)
|
||||
|
||||
@staticmethod
|
||||
def de_json(data, bot):
|
||||
|
||||
+650
-582
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2016
|
||||
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram CallbackGame."""
|
||||
|
||||
from telegram import TelegramObject
|
||||
|
||||
|
||||
class CallbackGame(TelegramObject):
|
||||
"""A placeholder, currently holds no information. Use BotFather to set up your game."""
|
||||
@@ -16,8 +16,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains a object that represents a Telegram
|
||||
CallbackQuery"""
|
||||
"""This module contains an object that represents a Telegram CallbackQuery"""
|
||||
|
||||
from telegram import TelegramObject, Message, User
|
||||
|
||||
@@ -25,14 +24,25 @@ from telegram import TelegramObject, Message, User
|
||||
class CallbackQuery(TelegramObject):
|
||||
"""This object represents a Telegram CallbackQuery."""
|
||||
|
||||
def __init__(self, id, from_user, data, bot=None, **kwargs):
|
||||
def __init__(self,
|
||||
id,
|
||||
from_user,
|
||||
chat_instance,
|
||||
message=None,
|
||||
data=None,
|
||||
inline_message_id=None,
|
||||
game_short_name=None,
|
||||
bot=None,
|
||||
**kwargs):
|
||||
# Required
|
||||
self.id = id
|
||||
self.from_user = from_user
|
||||
self.data = data
|
||||
self.chat_instance = chat_instance
|
||||
# Optionals
|
||||
self.message = kwargs.get('message')
|
||||
self.inline_message_id = kwargs.get('inline_message_id', '')
|
||||
self.message = message
|
||||
self.data = data
|
||||
self.inline_message_id = inline_message_id
|
||||
self.game_short_name = game_short_name
|
||||
|
||||
self.bot = bot
|
||||
|
||||
@@ -69,3 +79,52 @@ class CallbackQuery(TelegramObject):
|
||||
def answer(self, *args, **kwargs):
|
||||
"""Shortcut for ``bot.answerCallbackQuery(update.callback_query.id, *args, **kwargs)``"""
|
||||
return self.bot.answerCallbackQuery(self.id, *args, **kwargs)
|
||||
|
||||
def edit_message_text(self, *args, **kwargs):
|
||||
"""
|
||||
Shortcut for either ``bot.editMessageText(chat_id=update.callback_query.message.chat_id, \
|
||||
message_id=update.callback_query.message.message_id, \
|
||||
*args, **kwargs)``
|
||||
or ``bot.editMessageText(inline_message_id=update.callback_query.inline_message_id, \
|
||||
*args, **kwargs)``
|
||||
"""
|
||||
if self.inline_message_id:
|
||||
return self.bot.edit_message_text(
|
||||
inline_message_id=self.inline_message_id, *args, **kwargs)
|
||||
else:
|
||||
return self.bot.edit_message_text(
|
||||
chat_id=self.message.chat_id, message_id=self.message.message_id, *args, **kwargs)
|
||||
|
||||
def edit_message_caption(self, *args, **kwargs):
|
||||
"""
|
||||
Shortcut for either
|
||||
``bot.editMessageCaption(chat_id=update.callback_query.message.chat_id, \
|
||||
message_id=update.callback_query.message.message_id, \
|
||||
*args, **kwargs)``
|
||||
or
|
||||
``bot.editMessageCaption(inline_message_id=update.callback_query.inline_message_id, \
|
||||
*args, **kwargs)``
|
||||
"""
|
||||
if self.inline_message_id:
|
||||
return self.bot.edit_message_caption(
|
||||
inline_message_id=self.inline_message_id, *args, **kwargs)
|
||||
else:
|
||||
return self.bot.edit_message_caption(
|
||||
chat_id=self.message.chat_id, message_id=self.message.message_id, *args, **kwargs)
|
||||
|
||||
def edit_message_reply_markup(self, *args, **kwargs):
|
||||
"""
|
||||
Shortcut for either
|
||||
``bot.editMessageReplyMarkup(chat_id=update.callback_query.message.chat_id, \
|
||||
message_id=update.callback_query.message.message_id, \
|
||||
*args, **kwargs)``
|
||||
or
|
||||
``bot.editMessageReplyMarkup(inline_message_id=update.callback_query.inline_message_id, \
|
||||
*args, **kwargs)``
|
||||
"""
|
||||
if self.inline_message_id:
|
||||
return self.bot.edit_message_reply_markup(
|
||||
inline_message_id=self.inline_message_id, *args, **kwargs)
|
||||
else:
|
||||
return self.bot.edit_message_reply_markup(
|
||||
chat_id=self.message.chat_id, message_id=self.message.message_id, *args, **kwargs)
|
||||
|
||||
+23
-11
@@ -17,7 +17,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains a object that represents a Telegram Chat."""
|
||||
"""This module contains an object that represents a Telegram Chat."""
|
||||
|
||||
from telegram import TelegramObject
|
||||
|
||||
@@ -32,31 +32,43 @@ class Chat(TelegramObject):
|
||||
username (str): Username, for private chats and channels if available
|
||||
first_name (str): First name of the other party in a private chat
|
||||
last_name (str): Last name of the other party in a private chat
|
||||
all_members_are_admins (bool): True if a group has 'All Members Are Admins' enabled.
|
||||
|
||||
Args:
|
||||
id (int):
|
||||
type (str):
|
||||
**kwargs: Arbitrary keyword arguments.
|
||||
|
||||
Keyword Args:
|
||||
type (Optional[str]):
|
||||
title (Optional[str]):
|
||||
username(Optional[str]):
|
||||
first_name(Optional[str]):
|
||||
last_name(Optional[str]):
|
||||
bot (Optional[Bot]): The Bot to use for instance methods
|
||||
"""
|
||||
**kwargs (dict): Arbitrary keyword arguments.
|
||||
|
||||
"""
|
||||
PRIVATE = 'private'
|
||||
GROUP = 'group'
|
||||
SUPERGROUP = 'supergroup'
|
||||
CHANNEL = 'channel'
|
||||
|
||||
def __init__(self, id, type, bot=None, **kwargs):
|
||||
def __init__(self,
|
||||
id,
|
||||
type,
|
||||
title='',
|
||||
username='',
|
||||
first_name='',
|
||||
last_name='',
|
||||
all_members_are_admins=False,
|
||||
bot=None,
|
||||
**kwargs):
|
||||
# Required
|
||||
self.id = int(id)
|
||||
self.type = type
|
||||
# Optionals
|
||||
self.title = kwargs.get('title', '')
|
||||
self.username = kwargs.get('username', '')
|
||||
self.first_name = kwargs.get('first_name', '')
|
||||
self.last_name = kwargs.get('last_name', '')
|
||||
self.title = title
|
||||
self.username = username
|
||||
self.first_name = first_name
|
||||
self.last_name = last_name
|
||||
self.all_members_are_admins = all_members_are_admins
|
||||
|
||||
self.bot = bot
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains a object that represents a Telegram ChatAction."""
|
||||
"""This module contains an object that represents a Telegram ChatAction."""
|
||||
|
||||
|
||||
class ChatAction(object):
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains a object that represents a Telegram ChatMember."""
|
||||
"""This module contains an object that represents a Telegram ChatMember."""
|
||||
|
||||
from telegram import User, TelegramObject
|
||||
|
||||
@@ -32,8 +32,9 @@ class ChatMember(TelegramObject):
|
||||
Args:
|
||||
user (:class:`telegram.User`):
|
||||
status (str):
|
||||
"""
|
||||
**kwargs (dict): Arbitrary keyword arguments.
|
||||
|
||||
"""
|
||||
CREATOR = 'creator'
|
||||
ADMINISTRATOR = 'administrator'
|
||||
MEMBER = 'member'
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""
|
||||
This module contains a object that represents a Telegram ChosenInlineResult
|
||||
This module contains an object that represents a Telegram ChosenInlineResult
|
||||
"""
|
||||
|
||||
from telegram import TelegramObject, User, Location
|
||||
@@ -33,11 +33,16 @@ class ChosenInlineResult(TelegramObject):
|
||||
result_id (str):
|
||||
from_user (:class:`telegram.User`):
|
||||
query (str):
|
||||
location (:class:`telegram.Location`):
|
||||
inline_message_id (str):
|
||||
|
||||
Args:
|
||||
result_id (str):
|
||||
from_user (:class:`telegram.User`):
|
||||
query (str):
|
||||
location (Optional[:class:`telegram.Location`]):
|
||||
inline_message_id (Optional[str]):
|
||||
**kwargs (dict): Arbitrary keyword arguments.
|
||||
|
||||
"""
|
||||
|
||||
@@ -69,7 +74,7 @@ class ChosenInlineResult(TelegramObject):
|
||||
if not data:
|
||||
return None
|
||||
|
||||
# Required
|
||||
# Required
|
||||
data['from_user'] = User.de_json(data.pop('from'), bot)
|
||||
# Optionals
|
||||
data['location'] = Location.de_json(data.get('location'), bot)
|
||||
|
||||
+6
-7
@@ -16,7 +16,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains a object that represents a Telegram Contact."""
|
||||
"""This module contains an object that represents a Telegram Contact."""
|
||||
|
||||
from telegram import TelegramObject
|
||||
|
||||
@@ -33,20 +33,19 @@ class Contact(TelegramObject):
|
||||
Args:
|
||||
phone_number (str):
|
||||
first_name (str):
|
||||
**kwargs: Arbitrary keyword arguments.
|
||||
|
||||
Keyword Args:
|
||||
last_name (Optional[str]):
|
||||
user_id (Optional[int]):
|
||||
**kwargs: Arbitrary keyword arguments.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, phone_number, first_name, **kwargs):
|
||||
def __init__(self, phone_number, first_name, last_name='', user_id=0, **kwargs):
|
||||
# Required
|
||||
self.phone_number = str(phone_number)
|
||||
self.first_name = first_name
|
||||
# Optionals
|
||||
self.last_name = kwargs.get('last_name', '')
|
||||
self.user_id = int(kwargs.get('user_id', 0))
|
||||
self.last_name = last_name
|
||||
self.user_id = int(user_id)
|
||||
|
||||
@staticmethod
|
||||
def de_json(data, bot):
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains a object that represents a Telegram Document."""
|
||||
"""This module contains an object that represents a Telegram Document."""
|
||||
|
||||
from telegram import PhotoSize, TelegramObject
|
||||
|
||||
@@ -33,23 +33,22 @@ class Document(TelegramObject):
|
||||
|
||||
Args:
|
||||
file_id (str):
|
||||
**kwargs: Arbitrary keyword arguments.
|
||||
|
||||
Keyword Args:
|
||||
thumb (Optional[:class:`telegram.PhotoSize`]):
|
||||
file_name (Optional[str]):
|
||||
mime_type (Optional[str]):
|
||||
file_size (Optional[int]):
|
||||
**kwargs (dict): Arbitrary keyword arguments.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, file_id, **kwargs):
|
||||
def __init__(self, file_id, thumb=None, file_name='', mime_type='', file_size=0, **kwargs):
|
||||
# Required
|
||||
self.file_id = str(file_id)
|
||||
# Optionals
|
||||
self.thumb = kwargs.get('thumb')
|
||||
self.file_name = kwargs.get('file_name', '')
|
||||
self.mime_type = str(kwargs.get('mime_type', ''))
|
||||
self.file_size = int(kwargs.get('file_size', 0))
|
||||
self.thumb = thumb
|
||||
self.file_name = file_name
|
||||
self.mime_type = str(mime_type)
|
||||
self.file_size = int(file_size)
|
||||
|
||||
@staticmethod
|
||||
def de_json(data, bot):
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains a object that represents an Emoji.
|
||||
"""This module contains an object that represents an Emoji.
|
||||
|
||||
This module will be removed in the future.
|
||||
"""
|
||||
|
||||
+16
-4
@@ -16,7 +16,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains a object that represents a Telegram Error."""
|
||||
"""This module contains an object that represents a Telegram Error."""
|
||||
|
||||
|
||||
def _lstrip_str(in_s, lstr):
|
||||
@@ -94,8 +94,20 @@ class ChatMigrated(TelegramError):
|
||||
Args:
|
||||
new_chat_id (int):
|
||||
|
||||
Returns:
|
||||
"""
|
||||
super(ChatMigrated,
|
||||
self).__init__('Group migrated to supergroup. New chat id: {}'.format(new_chat_id))
|
||||
self.new_chat_id = new_chat_id
|
||||
|
||||
|
||||
class RetryAfter(TelegramError):
|
||||
|
||||
def __init__(self, retry_after):
|
||||
"""
|
||||
Args:
|
||||
retry_after (int):
|
||||
|
||||
"""
|
||||
super(ChatMigrated, self).__init__('Chat migrated')
|
||||
self.new_chat_id = new_chat_id
|
||||
super(RetryAfter,
|
||||
self).__init__('Flood control exceeded. Retry in {} seconds'.format(retry_after))
|
||||
self.retry_after = float(retry_after)
|
||||
|
||||
@@ -26,7 +26,8 @@ from .choseninlineresulthandler import ChosenInlineResultHandler
|
||||
from .commandhandler import CommandHandler
|
||||
from .handler import Handler
|
||||
from .inlinequeryhandler import InlineQueryHandler
|
||||
from .messagehandler import MessageHandler, Filters
|
||||
from .messagehandler import MessageHandler
|
||||
from .filters import BaseFilter, Filters
|
||||
from .regexhandler import RegexHandler
|
||||
from .stringcommandhandler import StringCommandHandler
|
||||
from .stringregexhandler import StringRegexHandler
|
||||
@@ -35,5 +36,5 @@ from .conversationhandler import ConversationHandler
|
||||
|
||||
__all__ = ('Dispatcher', 'JobQueue', 'Job', 'Updater', 'CallbackQueryHandler',
|
||||
'ChosenInlineResultHandler', 'CommandHandler', 'Handler', 'InlineQueryHandler',
|
||||
'MessageHandler', 'Filters', 'RegexHandler', 'StringCommandHandler',
|
||||
'MessageHandler', 'BaseFilter', 'Filters', 'RegexHandler', 'StringCommandHandler',
|
||||
'StringRegexHandler', 'TypeHandler', 'ConversationHandler')
|
||||
|
||||
@@ -52,6 +52,14 @@ class CallbackQueryHandler(Handler):
|
||||
pass_groupdict (optional[bool]): If the callback should be passed the
|
||||
result of ``re.match(pattern, data).groupdict()`` as a keyword
|
||||
argument called ``groupdict``. Default is ``False``
|
||||
pass_user_data (optional[bool]): If set to ``True``, a keyword argument called
|
||||
``user_data`` will be passed to the callback function. It will be a ``dict`` you
|
||||
can use to keep any data related to the user that sent the update. For each update of
|
||||
the same user, it will be the same ``dict``. Default is ``False``.
|
||||
pass_chat_data (optional[bool]): If set to ``True``, a keyword argument called
|
||||
``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``.
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
@@ -60,9 +68,15 @@ class CallbackQueryHandler(Handler):
|
||||
pass_job_queue=False,
|
||||
pattern=None,
|
||||
pass_groups=False,
|
||||
pass_groupdict=False):
|
||||
pass_groupdict=False,
|
||||
pass_user_data=False,
|
||||
pass_chat_data=False):
|
||||
super(CallbackQueryHandler, self).__init__(
|
||||
callback, pass_update_queue=pass_update_queue, pass_job_queue=pass_job_queue)
|
||||
callback,
|
||||
pass_update_queue=pass_update_queue,
|
||||
pass_job_queue=pass_job_queue,
|
||||
pass_user_data=pass_user_data,
|
||||
pass_chat_data=pass_chat_data)
|
||||
|
||||
if isinstance(pattern, string_types):
|
||||
pattern = re.compile(pattern)
|
||||
@@ -81,7 +95,7 @@ class CallbackQueryHandler(Handler):
|
||||
return True
|
||||
|
||||
def handle_update(self, update, dispatcher):
|
||||
optional_args = self.collect_optional_args(dispatcher)
|
||||
optional_args = self.collect_optional_args(dispatcher, update)
|
||||
if self.pattern:
|
||||
match = re.match(self.pattern, update.callback_query.data)
|
||||
|
||||
|
||||
@@ -40,17 +40,34 @@ class ChosenInlineResultHandler(Handler):
|
||||
``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.
|
||||
Default is ``False``.
|
||||
pass_user_data (optional[bool]): If set to ``True``, a keyword argument called
|
||||
``user_data`` will be passed to the callback function. It will be a ``dict`` you
|
||||
can use to keep any data related to the user that sent the update. For each update of
|
||||
the same user, it will be the same ``dict``. Default is ``False``.
|
||||
pass_chat_data (optional[bool]): If set to ``True``, a keyword argument called
|
||||
``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``.
|
||||
"""
|
||||
|
||||
def __init__(self, callback, pass_update_queue=False, pass_job_queue=False):
|
||||
def __init__(self,
|
||||
callback,
|
||||
pass_update_queue=False,
|
||||
pass_job_queue=False,
|
||||
pass_user_data=False,
|
||||
pass_chat_data=False):
|
||||
super(ChosenInlineResultHandler, self).__init__(
|
||||
callback, pass_update_queue=pass_update_queue, pass_job_queue=pass_job_queue)
|
||||
callback,
|
||||
pass_update_queue=pass_update_queue,
|
||||
pass_job_queue=pass_job_queue,
|
||||
pass_user_data=pass_user_data,
|
||||
pass_chat_data=pass_chat_data)
|
||||
|
||||
def check_update(self, update):
|
||||
return isinstance(update, Update) and update.chosen_inline_result
|
||||
|
||||
def handle_update(self, update, dispatcher):
|
||||
optional_args = self.collect_optional_args(dispatcher)
|
||||
optional_args = self.collect_optional_args(dispatcher, update)
|
||||
|
||||
return self.callback(dispatcher.bot, update, **optional_args)
|
||||
|
||||
|
||||
@@ -49,6 +49,14 @@ class CommandHandler(Handler):
|
||||
``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.
|
||||
Default is ``False``.
|
||||
pass_user_data (optional[bool]): If set to ``True``, a keyword argument called
|
||||
``user_data`` will be passed to the callback function. It will be a ``dict`` you
|
||||
can use to keep any data related to the user that sent the update. For each update of
|
||||
the same user, it will be the same ``dict``. Default is ``False``.
|
||||
pass_chat_data (optional[bool]): If set to ``True``, a keyword argument called
|
||||
``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``.
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
@@ -57,9 +65,15 @@ class CommandHandler(Handler):
|
||||
allow_edited=False,
|
||||
pass_args=False,
|
||||
pass_update_queue=False,
|
||||
pass_job_queue=False):
|
||||
pass_job_queue=False,
|
||||
pass_user_data=False,
|
||||
pass_chat_data=False):
|
||||
super(CommandHandler, self).__init__(
|
||||
callback, pass_update_queue=pass_update_queue, pass_job_queue=pass_job_queue)
|
||||
callback,
|
||||
pass_update_queue=pass_update_queue,
|
||||
pass_job_queue=pass_job_queue,
|
||||
pass_user_data=pass_user_data,
|
||||
pass_chat_data=pass_chat_data)
|
||||
self.command = command
|
||||
self.allow_edited = allow_edited
|
||||
self.pass_args = pass_args
|
||||
@@ -76,7 +90,7 @@ class CommandHandler(Handler):
|
||||
return False
|
||||
|
||||
def handle_update(self, update, dispatcher):
|
||||
optional_args = self.collect_optional_args(dispatcher)
|
||||
optional_args = self.collect_optional_args(dispatcher, update)
|
||||
|
||||
message = update.message or update.edited_message
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import logging
|
||||
|
||||
from telegram import Update
|
||||
from telegram.ext import Handler
|
||||
from telegram.utils.helpers import extract_chat_and_user
|
||||
from telegram.utils.promise import Promise
|
||||
|
||||
|
||||
@@ -115,29 +116,7 @@ class ConversationHandler(Handler):
|
||||
if not isinstance(update, Update):
|
||||
return False
|
||||
|
||||
user = None
|
||||
chat = None
|
||||
|
||||
if update.message:
|
||||
user = update.message.from_user
|
||||
chat = update.message.chat
|
||||
|
||||
elif update.edited_message:
|
||||
user = update.edited_message.from_user
|
||||
chat = update.edited_message.chat
|
||||
|
||||
elif update.inline_query:
|
||||
user = update.inline_query.from_user
|
||||
|
||||
elif update.chosen_inline_result:
|
||||
user = update.chosen_inline_result.from_user
|
||||
|
||||
elif update.callback_query:
|
||||
user = update.callback_query.from_user
|
||||
chat = update.callback_query.message.chat if update.callback_query.message else None
|
||||
|
||||
else:
|
||||
return False
|
||||
chat, user = extract_chat_and_user(update)
|
||||
|
||||
key = (chat.id, user.id) if chat else (None, user.id)
|
||||
state = self.conversations.get(key)
|
||||
|
||||
@@ -24,6 +24,7 @@ from functools import wraps
|
||||
from threading import Thread, Lock, Event, current_thread, BoundedSemaphore
|
||||
from time import sleep
|
||||
from uuid import uuid4
|
||||
from collections import defaultdict
|
||||
|
||||
from queue import Queue, Empty
|
||||
|
||||
@@ -84,6 +85,12 @@ class Dispatcher(object):
|
||||
self.bot = bot
|
||||
self.update_queue = update_queue
|
||||
self.job_queue = job_queue
|
||||
self.workers = workers
|
||||
|
||||
self.user_data = defaultdict(dict)
|
||||
""":type: dict[int, dict]"""
|
||||
self.chat_data = defaultdict(dict)
|
||||
""":type: dict[int, dict]"""
|
||||
|
||||
self.handlers = {}
|
||||
""":type: dict[int, list[Handler]"""
|
||||
@@ -105,8 +112,6 @@ class Dispatcher(object):
|
||||
else:
|
||||
self._set_singleton(None)
|
||||
|
||||
self._init_async_threads(uuid4(), workers)
|
||||
|
||||
@classmethod
|
||||
def _reset_singleton(cls):
|
||||
# NOTE: This method was added mainly for test_updater benefit and specifically pypy. Never
|
||||
@@ -193,6 +198,7 @@ class Dispatcher(object):
|
||||
self.logger.error(msg)
|
||||
raise TelegramError(msg)
|
||||
|
||||
self._init_async_threads(uuid4(), self.workers)
|
||||
self.running = True
|
||||
self.logger.debug('Dispatcher started')
|
||||
|
||||
|
||||
@@ -0,0 +1,216 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2016
|
||||
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
""" This module contains the Filters for use with the MessageHandler class """
|
||||
|
||||
|
||||
class BaseFilter(object):
|
||||
"""Base class for all Message Filters
|
||||
|
||||
Subclassing from this class filters to be combined using bitwise operators:
|
||||
|
||||
And:
|
||||
|
||||
>>> (Filters.text & Filters.entity(MENTION))
|
||||
|
||||
Or:
|
||||
|
||||
>>> (Filters.audio | Filters.video)
|
||||
|
||||
Also works with more than two filters:
|
||||
|
||||
>>> (Filters.text & (Filters.entity(URL) | Filters.entity(TEXT_LINK)))
|
||||
|
||||
If you want to create your own filters create a class inheriting from this class and implement
|
||||
a `filter` method that returns a boolean: `True` if the message should be handled, `False`
|
||||
otherwise. Note that the filters work only as class instances, not actual class objects
|
||||
(so remember to initialize your filter classes).
|
||||
"""
|
||||
|
||||
def __call__(self, message):
|
||||
return self.filter(message)
|
||||
|
||||
def __and__(self, other):
|
||||
return MergedFilter(self, and_filter=other)
|
||||
|
||||
def __or__(self, other):
|
||||
return MergedFilter(self, or_filter=other)
|
||||
|
||||
def filter(self, message):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class MergedFilter(BaseFilter):
|
||||
"""Represents a filter consisting of two other filters.
|
||||
|
||||
Args:
|
||||
base_filter: Filter 1 of the merged filter
|
||||
and_filter: Optional filter to "and" with base_filter. Mutually exclusive with or_filter.
|
||||
or_filter: Optional filter to "or" with base_filter. Mutually exclusive with and_filter.
|
||||
"""
|
||||
|
||||
def __init__(self, base_filter, and_filter=None, or_filter=None):
|
||||
self.base_filter = base_filter
|
||||
self.and_filter = and_filter
|
||||
self.or_filter = or_filter
|
||||
|
||||
def filter(self, message):
|
||||
if self.and_filter:
|
||||
return self.base_filter(message) and self.and_filter(message)
|
||||
elif self.or_filter:
|
||||
return self.base_filter(message) or self.or_filter(message)
|
||||
|
||||
def __str__(self):
|
||||
return ("<telegram.ext.filters.MergedFilter consisting of"
|
||||
" {} {} {}>").format(self.base_filter, "and" if self.and_filter else "or",
|
||||
self.and_filter or self.or_filter)
|
||||
|
||||
__repr__ = __str__
|
||||
|
||||
|
||||
class Filters(object):
|
||||
"""
|
||||
Predefined filters for use with the `filter` argument of :class:`telegram.ext.MessageHandler`.
|
||||
"""
|
||||
|
||||
class _All(BaseFilter):
|
||||
|
||||
def filter(self, message):
|
||||
return True
|
||||
|
||||
all = _All()
|
||||
|
||||
class _Text(BaseFilter):
|
||||
|
||||
def filter(self, message):
|
||||
return bool(message.text and not message.text.startswith('/'))
|
||||
|
||||
text = _Text()
|
||||
|
||||
class _Command(BaseFilter):
|
||||
|
||||
def filter(self, message):
|
||||
return bool(message.text and message.text.startswith('/'))
|
||||
|
||||
command = _Command()
|
||||
|
||||
class _Audio(BaseFilter):
|
||||
|
||||
def filter(self, message):
|
||||
return bool(message.audio)
|
||||
|
||||
audio = _Audio()
|
||||
|
||||
class _Document(BaseFilter):
|
||||
|
||||
def filter(self, message):
|
||||
return bool(message.document)
|
||||
|
||||
document = _Document()
|
||||
|
||||
class _Photo(BaseFilter):
|
||||
|
||||
def filter(self, message):
|
||||
return bool(message.photo)
|
||||
|
||||
photo = _Photo()
|
||||
|
||||
class _Sticker(BaseFilter):
|
||||
|
||||
def filter(self, message):
|
||||
return bool(message.sticker)
|
||||
|
||||
sticker = _Sticker()
|
||||
|
||||
class _Video(BaseFilter):
|
||||
|
||||
def filter(self, message):
|
||||
return bool(message.video)
|
||||
|
||||
video = _Video()
|
||||
|
||||
class _Voice(BaseFilter):
|
||||
|
||||
def filter(self, message):
|
||||
return bool(message.voice)
|
||||
|
||||
voice = _Voice()
|
||||
|
||||
class _Contact(BaseFilter):
|
||||
|
||||
def filter(self, message):
|
||||
return bool(message.contact)
|
||||
|
||||
contact = _Contact()
|
||||
|
||||
class _Location(BaseFilter):
|
||||
|
||||
def filter(self, message):
|
||||
return bool(message.location)
|
||||
|
||||
location = _Location()
|
||||
|
||||
class _Venue(BaseFilter):
|
||||
|
||||
def filter(self, message):
|
||||
return bool(message.venue)
|
||||
|
||||
venue = _Venue()
|
||||
|
||||
class _StatusUpdate(BaseFilter):
|
||||
|
||||
def filter(self, message):
|
||||
return bool(message.new_chat_member or message.left_chat_member
|
||||
or message.new_chat_title or message.new_chat_photo
|
||||
or message.delete_chat_photo or message.group_chat_created
|
||||
or message.supergroup_chat_created or message.channel_chat_created
|
||||
or message.migrate_to_chat_id or message.migrate_from_chat_id
|
||||
or message.pinned_message)
|
||||
|
||||
status_update = _StatusUpdate()
|
||||
|
||||
class _Forwarded(BaseFilter):
|
||||
|
||||
def filter(self, message):
|
||||
return bool(message.forward_date)
|
||||
|
||||
forwarded = _Forwarded()
|
||||
|
||||
class _Game(BaseFilter):
|
||||
|
||||
def filter(self, message):
|
||||
return bool(message.game)
|
||||
|
||||
game = _Game()
|
||||
|
||||
class entity(BaseFilter):
|
||||
"""Filters messages to only allow those which have a :class:`telegram.MessageEntity`
|
||||
where their `type` matches `entity_type`.
|
||||
|
||||
Args:
|
||||
entity_type: Entity type to check for. All types can be found as constants
|
||||
in :class:`telegram.MessageEntity`.
|
||||
|
||||
Returns: function to use as filter
|
||||
"""
|
||||
|
||||
def __init__(self, entity_type):
|
||||
self.entity_type = entity_type
|
||||
|
||||
def filter(self, message):
|
||||
return any([entity.type == self.entity_type for entity in message.entities])
|
||||
+27
-2
@@ -20,6 +20,7 @@
|
||||
Dispatcher """
|
||||
|
||||
from telegram.utils.deprecate import deprecate
|
||||
from telegram.utils.helpers import extract_chat_and_user
|
||||
|
||||
|
||||
class Handler(object):
|
||||
@@ -39,12 +40,27 @@ class Handler(object):
|
||||
``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.
|
||||
Default is ``False``.
|
||||
pass_user_data (optional[bool]): If set to ``True``, a keyword argument called
|
||||
``user_data`` will be passed to the callback function. It will be a ``dict`` you
|
||||
can use to keep any data related to the user that sent the update. For each update of
|
||||
the same user, it will be the same ``dict``. Default is ``False``.
|
||||
pass_chat_data (optional[bool]): If set to ``True``, a keyword argument called
|
||||
``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``.
|
||||
"""
|
||||
|
||||
def __init__(self, callback, pass_update_queue=False, pass_job_queue=False):
|
||||
def __init__(self,
|
||||
callback,
|
||||
pass_update_queue=False,
|
||||
pass_job_queue=False,
|
||||
pass_user_data=False,
|
||||
pass_chat_data=False):
|
||||
self.callback = callback
|
||||
self.pass_update_queue = pass_update_queue
|
||||
self.pass_job_queue = pass_job_queue
|
||||
self.pass_user_data = pass_user_data
|
||||
self.pass_chat_data = pass_chat_data
|
||||
|
||||
def check_update(self, update):
|
||||
"""
|
||||
@@ -74,7 +90,7 @@ class Handler(object):
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def collect_optional_args(self, dispatcher):
|
||||
def collect_optional_args(self, dispatcher, update=None):
|
||||
"""
|
||||
Prepares the optional arguments that are the same for all types of
|
||||
handlers
|
||||
@@ -83,10 +99,19 @@ class Handler(object):
|
||||
dispatcher (Dispatcher):
|
||||
"""
|
||||
optional_args = dict()
|
||||
|
||||
if self.pass_update_queue:
|
||||
optional_args['update_queue'] = dispatcher.update_queue
|
||||
if self.pass_job_queue:
|
||||
optional_args['job_queue'] = dispatcher.job_queue
|
||||
if self.pass_user_data or self.pass_chat_data:
|
||||
chat, user = extract_chat_and_user(update)
|
||||
|
||||
if self.pass_user_data:
|
||||
optional_args['user_data'] = dispatcher.user_data[user.id]
|
||||
|
||||
if self.pass_chat_data:
|
||||
optional_args['chat_data'] = dispatcher.chat_data[chat.id if chat else None]
|
||||
|
||||
return optional_args
|
||||
|
||||
|
||||
@@ -51,6 +51,14 @@ class InlineQueryHandler(Handler):
|
||||
pass_groupdict (optional[bool]): If the callback should be passed the
|
||||
result of ``re.match(pattern, query).groupdict()`` as a keyword
|
||||
argument called ``groupdict``. Default is ``False``
|
||||
pass_user_data (optional[bool]): If set to ``True``, a keyword argument called
|
||||
``user_data`` will be passed to the callback function. It will be a ``dict`` you
|
||||
can use to keep any data related to the user that sent the update. For each update of
|
||||
the same user, it will be the same ``dict``. Default is ``False``.
|
||||
pass_chat_data (optional[bool]): If set to ``True``, a keyword argument called
|
||||
``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``.
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
@@ -59,9 +67,15 @@ class InlineQueryHandler(Handler):
|
||||
pass_job_queue=False,
|
||||
pattern=None,
|
||||
pass_groups=False,
|
||||
pass_groupdict=False):
|
||||
pass_groupdict=False,
|
||||
pass_user_data=False,
|
||||
pass_chat_data=False):
|
||||
super(InlineQueryHandler, self).__init__(
|
||||
callback, pass_update_queue=pass_update_queue, pass_job_queue=pass_job_queue)
|
||||
callback,
|
||||
pass_update_queue=pass_update_queue,
|
||||
pass_job_queue=pass_job_queue,
|
||||
pass_user_data=pass_user_data,
|
||||
pass_chat_data=pass_chat_data)
|
||||
|
||||
if isinstance(pattern, string_types):
|
||||
pattern = re.compile(pattern)
|
||||
@@ -80,7 +94,7 @@ class InlineQueryHandler(Handler):
|
||||
return True
|
||||
|
||||
def handle_update(self, update, dispatcher):
|
||||
optional_args = self.collect_optional_args(dispatcher)
|
||||
optional_args = self.collect_optional_args(dispatcher, update)
|
||||
if self.pattern:
|
||||
match = re.match(self.pattern, update.inline_query.query)
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
import logging
|
||||
import time
|
||||
import warnings
|
||||
from threading import Thread, Lock, Event
|
||||
from queue import PriorityQueue, Empty
|
||||
|
||||
@@ -30,15 +31,19 @@ class JobQueue(object):
|
||||
Attributes:
|
||||
queue (PriorityQueue):
|
||||
bot (Bot):
|
||||
prevent_autostart (Optional[bool]): If ``True``, the job queue will not be started
|
||||
automatically. Defaults to ``False``
|
||||
|
||||
Args:
|
||||
bot (Bot): The bot instance that should be passed to the jobs
|
||||
|
||||
Deprecated: 5.2
|
||||
prevent_autostart (Optional[bool]): Thread does not start during initialisation.
|
||||
Use `start` method instead.
|
||||
"""
|
||||
|
||||
def __init__(self, bot, prevent_autostart=False):
|
||||
def __init__(self, bot, prevent_autostart=None):
|
||||
if prevent_autostart is not None:
|
||||
warnings.warn("prevent_autostart is being deprecated, use `start` method instead.")
|
||||
|
||||
self.queue = PriorityQueue()
|
||||
self.bot = bot
|
||||
self.logger = logging.getLogger(self.__class__.__name__)
|
||||
@@ -51,12 +56,8 @@ class JobQueue(object):
|
||||
""":type: float"""
|
||||
self._running = False
|
||||
|
||||
if not prevent_autostart:
|
||||
self.logger.debug('Auto-starting %s', self.__class__.__name__)
|
||||
self.start()
|
||||
|
||||
def put(self, job, next_t=None):
|
||||
"""Queue a new job. If the JobQueue is not running, it will be started.
|
||||
"""Queue a new job.
|
||||
|
||||
Args:
|
||||
job (Job): The ``Job`` instance representing the new job
|
||||
|
||||
@@ -17,92 +17,13 @@
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
""" This module contains the MessageHandler class """
|
||||
import warnings
|
||||
|
||||
from .handler import Handler
|
||||
from telegram import Update
|
||||
from telegram.utils.deprecate import deprecate
|
||||
|
||||
|
||||
class Filters(object):
|
||||
"""
|
||||
Convenient namespace (class) & methods for the filter funcs of the
|
||||
MessageHandler class.
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def text(message):
|
||||
return message.text and not message.text.startswith('/')
|
||||
|
||||
@staticmethod
|
||||
def command(message):
|
||||
return message.text and message.text.startswith('/')
|
||||
|
||||
@staticmethod
|
||||
def audio(message):
|
||||
return bool(message.audio)
|
||||
|
||||
@staticmethod
|
||||
def document(message):
|
||||
return bool(message.document)
|
||||
|
||||
@staticmethod
|
||||
def photo(message):
|
||||
return bool(message.photo)
|
||||
|
||||
@staticmethod
|
||||
def sticker(message):
|
||||
return bool(message.sticker)
|
||||
|
||||
@staticmethod
|
||||
def video(message):
|
||||
return bool(message.video)
|
||||
|
||||
@staticmethod
|
||||
def voice(message):
|
||||
return bool(message.voice)
|
||||
|
||||
@staticmethod
|
||||
def contact(message):
|
||||
return bool(message.contact)
|
||||
|
||||
@staticmethod
|
||||
def location(message):
|
||||
return bool(message.location)
|
||||
|
||||
@staticmethod
|
||||
def venue(message):
|
||||
return bool(message.venue)
|
||||
|
||||
@staticmethod
|
||||
def status_update(message):
|
||||
return bool(message.new_chat_member or message.left_chat_member or message.new_chat_title
|
||||
or message.new_chat_photo or message.delete_chat_photo
|
||||
or message.group_chat_created or message.supergroup_chat_created
|
||||
or message.channel_chat_created or message.migrate_to_chat_id
|
||||
or message.migrate_from_chat_id or message.pinned_message)
|
||||
|
||||
@staticmethod
|
||||
def forwarded(message):
|
||||
return bool(message.forward_date)
|
||||
|
||||
@staticmethod
|
||||
def entity(entity_type):
|
||||
"""Filters messages to only allow those which have a :class:`telegram.MessageEntity`
|
||||
where their `type` matches `entity_type`.
|
||||
|
||||
Args:
|
||||
entity_type: Entity type to check for. All types can be found as constants
|
||||
in :class:`telegram.MessageEntity`.
|
||||
|
||||
Returns: function to use as filter
|
||||
"""
|
||||
|
||||
def entities_filter(message):
|
||||
return any([entity.type == entity_type for entity in message.entities])
|
||||
|
||||
return entities_filter
|
||||
|
||||
|
||||
class MessageHandler(Handler):
|
||||
"""
|
||||
Handler class to handle telegram messages. Messages are Telegram Updates
|
||||
@@ -110,12 +31,10 @@ class MessageHandler(Handler):
|
||||
updates.
|
||||
|
||||
Args:
|
||||
filters (list[function]): A list of filter functions. Standard filters
|
||||
can be found in the Filters class above.
|
||||
| Each `function` takes ``Update`` as arg and returns ``bool``.
|
||||
| All messages that match at least one of those filters will be
|
||||
accepted. If ``bool(filters)`` evaluates to ``False``, messages are
|
||||
not filtered.
|
||||
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
|
||||
operators (& for and, | for or).
|
||||
callback (function): A function that takes ``bot, update`` as
|
||||
positional arguments. It will be called when the ``check_update``
|
||||
has determined that an update should be processed by this handler.
|
||||
@@ -124,6 +43,14 @@ class MessageHandler(Handler):
|
||||
pass_update_queue (optional[bool]): If the handler should be passed the
|
||||
update queue as a keyword argument called ``update_queue``. It can
|
||||
be used to insert updates. Default is ``False``
|
||||
pass_user_data (optional[bool]): If set to ``True``, a keyword argument called
|
||||
``user_data`` will be passed to the callback function. It will be a ``dict`` you
|
||||
can use to keep any data related to the user that sent the update. For each update of
|
||||
the same user, it will be the same ``dict``. Default is ``False``.
|
||||
pass_chat_data (optional[bool]): If set to ``True``, a keyword argument called
|
||||
``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``.
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
@@ -131,12 +58,25 @@ class MessageHandler(Handler):
|
||||
callback,
|
||||
allow_edited=False,
|
||||
pass_update_queue=False,
|
||||
pass_job_queue=False):
|
||||
pass_job_queue=False,
|
||||
pass_user_data=False,
|
||||
pass_chat_data=False):
|
||||
super(MessageHandler, self).__init__(
|
||||
callback, pass_update_queue=pass_update_queue, pass_job_queue=pass_job_queue)
|
||||
callback,
|
||||
pass_update_queue=pass_update_queue,
|
||||
pass_job_queue=pass_job_queue,
|
||||
pass_user_data=pass_user_data,
|
||||
pass_chat_data=pass_chat_data)
|
||||
self.filters = filters
|
||||
self.allow_edited = allow_edited
|
||||
|
||||
# We put this up here instead of with the rest of checking code
|
||||
# in check_update since we don't wanna spam a ton
|
||||
if isinstance(self.filters, list):
|
||||
warnings.warn('Using a list of filters in MessageHandler is getting '
|
||||
'deprecated, please use bitwise operators (& and |) '
|
||||
'instead. More info: https://git.io/vPTbc.')
|
||||
|
||||
def check_update(self, update):
|
||||
if (isinstance(update, Update)
|
||||
and (update.message or update.edited_message and self.allow_edited)):
|
||||
@@ -146,7 +86,10 @@ class MessageHandler(Handler):
|
||||
|
||||
else:
|
||||
message = update.message or update.edited_message
|
||||
res = any(func(message) for func in self.filters)
|
||||
if isinstance(self.filters, list):
|
||||
res = any(func(message) for func in self.filters)
|
||||
else:
|
||||
res = self.filters(message)
|
||||
|
||||
else:
|
||||
res = False
|
||||
@@ -154,12 +97,11 @@ class MessageHandler(Handler):
|
||||
return res
|
||||
|
||||
def handle_update(self, update, dispatcher):
|
||||
optional_args = self.collect_optional_args(dispatcher)
|
||||
optional_args = self.collect_optional_args(dispatcher, update)
|
||||
|
||||
return self.callback(dispatcher.bot, update, **optional_args)
|
||||
|
||||
# old non-PEP8 Handler methods
|
||||
|
||||
# old non-PEP8 Handler methods
|
||||
m = "telegram.MessageHandler."
|
||||
checkUpdate = deprecate(check_update, m + "checkUpdate", m + "check_update")
|
||||
handleUpdate = deprecate(handle_update, m + "handleUpdate", m + "handle_update")
|
||||
|
||||
@@ -53,6 +53,14 @@ class RegexHandler(Handler):
|
||||
``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.
|
||||
Default is ``False``.
|
||||
pass_user_data (optional[bool]): If set to ``True``, a keyword argument called
|
||||
``user_data`` will be passed to the callback function. It will be a ``dict`` you
|
||||
can use to keep any data related to the user that sent the update. For each update of
|
||||
the same user, it will be the same ``dict``. Default is ``False``.
|
||||
pass_chat_data (optional[bool]): If set to ``True``, a keyword argument called
|
||||
``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``.
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
@@ -61,9 +69,15 @@ class RegexHandler(Handler):
|
||||
pass_groups=False,
|
||||
pass_groupdict=False,
|
||||
pass_update_queue=False,
|
||||
pass_job_queue=False):
|
||||
pass_job_queue=False,
|
||||
pass_user_data=False,
|
||||
pass_chat_data=False):
|
||||
super(RegexHandler, self).__init__(
|
||||
callback, pass_update_queue=pass_update_queue, pass_job_queue=pass_job_queue)
|
||||
callback,
|
||||
pass_update_queue=pass_update_queue,
|
||||
pass_job_queue=pass_job_queue,
|
||||
pass_user_data=pass_user_data,
|
||||
pass_chat_data=pass_chat_data)
|
||||
|
||||
if isinstance(pattern, string_types):
|
||||
pattern = re.compile(pattern)
|
||||
@@ -73,14 +87,14 @@ class RegexHandler(Handler):
|
||||
self.pass_groupdict = pass_groupdict
|
||||
|
||||
def check_update(self, update):
|
||||
if (isinstance(update, Update) and update.message and update.message.text):
|
||||
if isinstance(update, Update) and update.message and update.message.text:
|
||||
match = re.match(self.pattern, update.message.text)
|
||||
return bool(match)
|
||||
else:
|
||||
return False
|
||||
|
||||
def handle_update(self, update, dispatcher):
|
||||
optional_args = self.collect_optional_args(dispatcher)
|
||||
optional_args = self.collect_optional_args(dispatcher, update)
|
||||
match = re.match(self.pattern, update.message.text)
|
||||
|
||||
if self.pass_groups:
|
||||
|
||||
@@ -30,7 +30,7 @@ from queue import Queue
|
||||
|
||||
from telegram import Bot, TelegramError
|
||||
from telegram.ext import Dispatcher, JobQueue
|
||||
from telegram.error import Unauthorized, InvalidToken
|
||||
from telegram.error import Unauthorized, InvalidToken, RetryAfter
|
||||
from telegram.utils.request import Request
|
||||
from telegram.utils.webhookhandler import (WebhookServer, WebhookHandler)
|
||||
|
||||
@@ -61,8 +61,6 @@ class Updater(object):
|
||||
bot (Optional[Bot]): A pre-initialized bot instance. If a pre-initizlied bot is used, it is
|
||||
the user's responsibility to create it using a `Request` instance with a large enough
|
||||
connection pool.
|
||||
job_queue_tick_interval(Optional[float]): The interval the queue should
|
||||
be checked for new tasks. Defaults to 1.0
|
||||
|
||||
Raises:
|
||||
ValueError: If both `token` and `bot` are passed or none of them.
|
||||
@@ -157,6 +155,7 @@ class Updater(object):
|
||||
self.running = True
|
||||
|
||||
# Create & start threads
|
||||
self.job_queue.start()
|
||||
self._init_thread(self.dispatcher.start, "dispatcher")
|
||||
self._init_thread(self._start_polling, "updater", poll_interval, timeout,
|
||||
network_delay, bootstrap_retries, clean)
|
||||
@@ -208,6 +207,7 @@ class Updater(object):
|
||||
self.running = True
|
||||
|
||||
# Create & start threads
|
||||
self.job_queue.start()
|
||||
self._init_thread(self.dispatcher.start, "dispatcher"),
|
||||
self._init_thread(self._start_webhook, "updater", listen, port, url_path, cert,
|
||||
key, bootstrap_retries, clean, webhook_url)
|
||||
@@ -231,6 +231,9 @@ class Updater(object):
|
||||
try:
|
||||
updates = self.bot.getUpdates(
|
||||
self.last_update_id, timeout=timeout, network_delay=network_delay)
|
||||
except RetryAfter as e:
|
||||
self.logger.info(str(e))
|
||||
cur_interval = 0.5 + e.retry_after
|
||||
except TelegramError as te:
|
||||
self.logger.error("Error while getting Updates: {0}".format(te))
|
||||
|
||||
@@ -327,6 +330,7 @@ class Updater(object):
|
||||
# Disable webhook for cleaning
|
||||
self.bot.setWebhook(webhook_url='')
|
||||
self._clean_updates()
|
||||
sleep(1)
|
||||
|
||||
self.bot.setWebhook(webhook_url=webhook_url, certificate=cert)
|
||||
except (Unauthorized, InvalidToken):
|
||||
|
||||
+5
-7
@@ -16,7 +16,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains a object that represents a Telegram File."""
|
||||
"""This module contains an object that represents a Telegram File."""
|
||||
|
||||
from os.path import basename
|
||||
|
||||
@@ -34,21 +34,19 @@ class File(TelegramObject):
|
||||
Args:
|
||||
file_id (str):
|
||||
bot (telegram.Bot):
|
||||
**kwargs: Arbitrary keyword arguments.
|
||||
|
||||
Keyword Args:
|
||||
file_size (Optional[int]):
|
||||
file_path (Optional[str]):
|
||||
**kwargs (dict): Arbitrary keyword arguments.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, file_id, bot, **kwargs):
|
||||
def __init__(self, file_id, bot, file_size=0, file_path='', **kwargs):
|
||||
# Required
|
||||
self.file_id = str(file_id)
|
||||
|
||||
# Optionals
|
||||
self.file_size = int(kwargs.get('file_size', 0))
|
||||
self.file_path = str(kwargs.get('file_path', ''))
|
||||
self.file_size = int(file_size)
|
||||
self.file_path = str(file_path)
|
||||
|
||||
self.bot = bot
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains a object that represents a Telegram ForceReply."""
|
||||
"""This module contains an object that represents a Telegram ForceReply."""
|
||||
|
||||
from telegram import ReplyMarkup
|
||||
|
||||
@@ -30,17 +30,16 @@ class ForceReply(ReplyMarkup):
|
||||
|
||||
Args:
|
||||
force_reply (bool):
|
||||
**kwargs: Arbitrary keyword arguments.
|
||||
|
||||
Keyword Args:
|
||||
selective (Optional[bool]):
|
||||
**kwargs (dict): Arbitrary keyword arguments.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, force_reply=True, **kwargs):
|
||||
def __init__(self, force_reply=True, selective=False, **kwargs):
|
||||
# Required
|
||||
self.force_reply = bool(force_reply)
|
||||
# Optionals
|
||||
self.selective = bool(kwargs.get('selective', False))
|
||||
self.selective = bool(selective)
|
||||
|
||||
@staticmethod
|
||||
def de_json(data, bot):
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2016
|
||||
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram Game."""
|
||||
|
||||
import sys
|
||||
|
||||
from telegram import MessageEntity, TelegramObject, Animation, PhotoSize
|
||||
|
||||
|
||||
class Game(TelegramObject):
|
||||
"""This object represents a Telegram Game.
|
||||
|
||||
Attributes:
|
||||
title (str): Title of the game.
|
||||
description (str): Description of the game.
|
||||
photo (list[:class:`telegram.PhotoSize`]): List of photos that will be displayed in the
|
||||
game message in chats.
|
||||
|
||||
Keyword Args:
|
||||
text (Optional[str]): Brief description of the game or high scores included in the game
|
||||
message. Can be automatically edited to include current high scores for the game when
|
||||
the bot calls setGameScore, or manually edited using editMessageText.
|
||||
0-4096 characters.
|
||||
text_entities (Optional[list[:class:`telegram.MessageEntity`]]): Special entities that
|
||||
appear in text, such as usernames, URLs, bot commands, etc.
|
||||
animation (Optional[:class:`telegram.Animation`]): Animation that will be displayed in the
|
||||
game message in chats. Upload via BotFather.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
title,
|
||||
description,
|
||||
photo,
|
||||
text='',
|
||||
text_entities=None,
|
||||
animation=None,
|
||||
**kwargs):
|
||||
self.title = title
|
||||
self.description = description
|
||||
self.photo = photo
|
||||
self.text = text
|
||||
self.text_entities = text_entities
|
||||
self.animation = animation
|
||||
|
||||
@staticmethod
|
||||
def de_json(data, bot):
|
||||
"""
|
||||
Args:
|
||||
data (dict):
|
||||
bot (telegram.Bot):
|
||||
|
||||
Returns:
|
||||
telegram.Game:
|
||||
|
||||
"""
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data['photo'] = PhotoSize.de_list(data.get('photo'), bot)
|
||||
data['text_entities'] = MessageEntity.de_list(data.get('text_entities'), bot)
|
||||
data['animation'] = Animation.de_json(data.get('animation'), bot)
|
||||
|
||||
return Game(**data)
|
||||
|
||||
def to_dict(self):
|
||||
"""
|
||||
Returns:
|
||||
dict:
|
||||
"""
|
||||
data = super(Game, self).to_dict()
|
||||
|
||||
data['photo'] = [p.to_dict() for p in self.photo]
|
||||
data['text_entities'] = [x.to_dict() for x in self.text_entities]
|
||||
|
||||
return data
|
||||
|
||||
def parse_text_entity(self, entity):
|
||||
"""
|
||||
Returns the text from a given :class:`telegram.MessageEntity`.
|
||||
|
||||
Note:
|
||||
This method is present because Telegram calculates the offset and length in
|
||||
UTF-16 codepoint pairs, which some versions of Python don't handle automatically.
|
||||
(That is, you can't just slice ``Message.text`` with the offset and length.)
|
||||
|
||||
Args:
|
||||
entity (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
|
||||
"""
|
||||
# Is it a narrow build, if so we don't need to convert
|
||||
if sys.maxunicode == 0xffff:
|
||||
return self.text[entity.offset:entity.offset + entity.length]
|
||||
else:
|
||||
entity_text = self.text.encode('utf-16-le')
|
||||
entity_text = entity_text[entity.offset * 2:(entity.offset + entity.length) * 2]
|
||||
|
||||
return entity_text.decode('utf-16-le')
|
||||
|
||||
def parse_text_entities(self, types=None):
|
||||
"""
|
||||
Returns a ``dict`` that maps :class:`telegram.MessageEntity` to ``str``.
|
||||
It contains entities from this message filtered by their ``type`` attribute as the key, and
|
||||
the text that each entity belongs to as the value of the ``dict``.
|
||||
|
||||
Note:
|
||||
This method should always be used instead of the ``entities`` attribute, since it
|
||||
calculates the correct substring from the message text based on UTF-16 codepoints.
|
||||
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.
|
||||
Defaults to a list of all types. All types can be found as constants in
|
||||
:class:`telegram.MessageEntity`.
|
||||
|
||||
Returns:
|
||||
dict[:class:`telegram.MessageEntity`, ``str``]: A dictionary of entities mapped to the
|
||||
text that belongs to them, calculated based on UTF-16 codepoints.
|
||||
"""
|
||||
if types is None:
|
||||
types = MessageEntity.ALL_TYPES
|
||||
|
||||
return {
|
||||
entity: self.parse_text_entity(entity)
|
||||
for entity in self.text_entities if entity.type in types
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2016
|
||||
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram GameHighScore."""
|
||||
|
||||
from telegram import TelegramObject, User
|
||||
|
||||
|
||||
class GameHighScore(TelegramObject):
|
||||
"""This object represents a Telegram GameHighScore.
|
||||
|
||||
Attributes:
|
||||
position (int): Position in high score table for the game.
|
||||
user (:class:`telegram.User`): User object.
|
||||
score (int): Score.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, position, user, score):
|
||||
self.position = position
|
||||
self.user = user
|
||||
self.score = score
|
||||
|
||||
@staticmethod
|
||||
def de_json(data, bot):
|
||||
"""
|
||||
Args:
|
||||
data (dict):
|
||||
bot (telegram.Bot):
|
||||
|
||||
Returns:
|
||||
telegram.Game:
|
||||
"""
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data['user'] = User.de_json(data.get('user'), bot)
|
||||
|
||||
return GameHighScore(**data)
|
||||
@@ -16,7 +16,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains a object that represents a Telegram
|
||||
"""This module contains an object that represents a Telegram
|
||||
InlineKeyboardButton"""
|
||||
|
||||
from telegram import TelegramObject
|
||||
@@ -30,26 +30,37 @@ class InlineKeyboardButton(TelegramObject):
|
||||
url (str):
|
||||
callback_data (str):
|
||||
switch_inline_query (str):
|
||||
switch_inline_query_current_chat (str):
|
||||
callback_game (:class:`telegram.CallbackGame`):
|
||||
|
||||
Args:
|
||||
text (str):
|
||||
**kwargs: Arbitrary keyword arguments.
|
||||
|
||||
Keyword Args:
|
||||
url (Optional[str]):
|
||||
callback_data (Optional[str]):
|
||||
switch_inline_query (Optional[str]):
|
||||
text (str): Label text on the button.
|
||||
url (Optional[str]): HTTP url to be opened when button is pressed.
|
||||
callback_data (Optional[str]): Data to be sent in a callback query to the bot when button
|
||||
is pressed, 1-64 bytes.
|
||||
switch_inline_query (Optional[str]): If set, pressing the button will prompt the user to
|
||||
select one of their chats, open that chat and insert the bot's username and the
|
||||
specified inline query in the input field. Can be empty, in which case just the bot's
|
||||
username will be inserted.
|
||||
switch_inline_query_current_chat (Optional[str]): If set, pressing the button will insert
|
||||
the bot's username and the specified inline query in the current chat's input field.
|
||||
Can be empty, in which case only the bot's username will be inserted.
|
||||
callback_game (Optional[:class:`telegram.CallbackGame`]): Description of the game that will
|
||||
be launched when the user presses the button.
|
||||
**kwargs (dict): Arbitrary keyword arguments.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, text, **kwargs):
|
||||
def __init__(self, text, url=None, callback_data=None, switch_inline_query=None, **kwargs):
|
||||
# Required
|
||||
self.text = text
|
||||
|
||||
# Optionals
|
||||
self.url = kwargs.get('url')
|
||||
self.callback_data = kwargs.get('callback_data')
|
||||
self.switch_inline_query = kwargs.get('switch_inline_query')
|
||||
self.url = url
|
||||
self.callback_data = callback_data
|
||||
self.switch_inline_query = switch_inline_query
|
||||
self.switch_inline_query_current_chat = kwargs.get('switch_inline_query_current_chat')
|
||||
self.callback_game = kwargs.get('callback_game')
|
||||
|
||||
@staticmethod
|
||||
def de_json(data, bot):
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains a object that represents a Telegram
|
||||
"""This module contains an object that represents a Telegram
|
||||
InlineKeyboardMarkup"""
|
||||
|
||||
from telegram import ReplyMarkup, InlineKeyboardButton
|
||||
@@ -30,6 +30,7 @@ class InlineKeyboardMarkup(ReplyMarkup):
|
||||
|
||||
Args:
|
||||
inline_keyboard (List[List[:class:`telegram.InlineKeyboardButton`]]):
|
||||
**kwargs (dict): Arbitrary keyword arguments.
|
||||
|
||||
"""
|
||||
|
||||
@@ -46,14 +47,17 @@ class InlineKeyboardMarkup(ReplyMarkup):
|
||||
|
||||
Returns:
|
||||
telegram.InlineKeyboardMarkup:
|
||||
|
||||
"""
|
||||
data = super(InlineKeyboardMarkup, InlineKeyboardMarkup).de_json(data, bot)
|
||||
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data['inline_keyboard'] = [InlineKeyboardButton.de_list(inline_keyboard, bot)
|
||||
for inline_keyboard in data['inline_keyboard']]
|
||||
data['inline_keyboard'] = [
|
||||
InlineKeyboardButton.de_list(inline_keyboard, bot)
|
||||
for inline_keyboard in data['inline_keyboard']
|
||||
]
|
||||
|
||||
return InlineKeyboardMarkup(**data)
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains a object that represents a Telegram InlineQuery"""
|
||||
"""This module contains an object that represents a Telegram InlineQuery"""
|
||||
|
||||
from telegram import TelegramObject, User, Location
|
||||
|
||||
@@ -38,14 +38,13 @@ class InlineQuery(TelegramObject):
|
||||
from_user (:class:`telegram.User`):
|
||||
query (str):
|
||||
offset (str):
|
||||
**kwargs: Arbitrary keyword arguments.
|
||||
|
||||
Keyword Args:
|
||||
location (optional[:class:`telegram.Location`]):
|
||||
bot (Optional[Bot]): The Bot to use for instance methods
|
||||
**kwargs (dict): Arbitrary keyword arguments.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, id, from_user, query, offset, bot=None, **kwargs):
|
||||
def __init__(self, id, from_user, query, offset, location=None, bot=None, **kwargs):
|
||||
# Required
|
||||
self.id = id
|
||||
self.from_user = from_user
|
||||
@@ -53,7 +52,7 @@ class InlineQuery(TelegramObject):
|
||||
self.offset = offset
|
||||
|
||||
# Optional
|
||||
self.location = kwargs.get('location')
|
||||
self.location = location
|
||||
|
||||
self.bot = bot
|
||||
|
||||
|
||||
@@ -26,12 +26,13 @@ class InlineQueryResult(TelegramObject):
|
||||
"""This object represents a Telegram InlineQueryResult.
|
||||
|
||||
Attributes:
|
||||
type (str):
|
||||
id (str):
|
||||
type (str): Type of the result.
|
||||
id (str): Unique identifier for this result, 1-64 Bytes
|
||||
|
||||
Args:
|
||||
type (str):
|
||||
type (str): Type of the result.
|
||||
id (str): Unique identifier for this result, 1-64 Bytes
|
||||
**kwargs (dict): Arbitrary keyword arguments.
|
||||
|
||||
"""
|
||||
|
||||
|
||||
@@ -42,21 +42,20 @@ class InlineQueryResultArticle(InlineQueryResult):
|
||||
|
||||
parse_mode (str): Use :class:`InputTextMessageContent` instead.
|
||||
|
||||
disable_web_page_preview (bool): Use :class:`InputTextMessageContent`
|
||||
instead.
|
||||
disable_web_page_preview (bool): Use :class:`InputTextMessageContent` instead.
|
||||
|
||||
Args:
|
||||
id (str): Unique identifier for this result, 1-64 Bytes
|
||||
title (str):
|
||||
reply_markup (:class:`telegram.ReplyMarkup`):
|
||||
|
||||
Keyword Args:
|
||||
url (Optional[str]):
|
||||
hide_url (Optional[bool]):
|
||||
description (Optional[str]):
|
||||
thumb_url (Optional[str]):
|
||||
thumb_width (Optional[int]):
|
||||
thumb_height (Optional[int]):
|
||||
**kwargs (dict): Arbitrary keyword arguments.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
|
||||
@@ -33,29 +33,27 @@ class InlineQueryResultAudio(InlineQueryResult):
|
||||
title (str):
|
||||
performer (Optional[str]):
|
||||
audio_duration (Optional[str]):
|
||||
caption (Optional[str]):
|
||||
reply_markup (Optional[:class:`telegram.InlineKeyboardMarkup`]):
|
||||
input_message_content (Optional[
|
||||
:class:`telegram.input_message_content`]):
|
||||
input_message_content (Optional[:class:`telegram.input_message_content`]):
|
||||
|
||||
Deprecated: 4.0
|
||||
message_text (str): Use :class:`InputTextMessageContent` instead.
|
||||
|
||||
parse_mode (str): Use :class:`InputTextMessageContent` instead.
|
||||
|
||||
disable_web_page_preview (bool): Use :class:`InputTextMessageContent`
|
||||
instead.
|
||||
disable_web_page_preview (bool): Use :class:`InputTextMessageContent` instead.
|
||||
|
||||
Args:
|
||||
audio_url (str):
|
||||
title (str):
|
||||
**kwargs: Arbitrary keyword arguments.
|
||||
|
||||
Keyword Args:
|
||||
performer (Optional[str]):
|
||||
audio_duration (Optional[str]):
|
||||
caption (Optional[str]):
|
||||
reply_markup (Optional[:class:`telegram.InlineKeyboardMarkup`]):
|
||||
input_message_content (Optional[
|
||||
:class:`telegram.input_message_content`]):
|
||||
input_message_content (Optional[:class:`telegram.input_message_content`]):
|
||||
**kwargs (dict): Arbitrary keyword arguments.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
@@ -64,6 +62,7 @@ class InlineQueryResultAudio(InlineQueryResult):
|
||||
title,
|
||||
performer=None,
|
||||
audio_duration=None,
|
||||
caption=None,
|
||||
reply_markup=None,
|
||||
input_message_content=None,
|
||||
**kwargs):
|
||||
@@ -78,6 +77,8 @@ class InlineQueryResultAudio(InlineQueryResult):
|
||||
self.performer = performer
|
||||
if audio_duration:
|
||||
self.audio_duration = audio_duration
|
||||
if caption:
|
||||
self.caption = caption
|
||||
if reply_markup:
|
||||
self.reply_markup = reply_markup
|
||||
if input_message_content:
|
||||
|
||||
@@ -23,42 +23,47 @@ from telegram import InlineQueryResult, InlineKeyboardMarkup, InputMessageConten
|
||||
|
||||
|
||||
class InlineQueryResultCachedAudio(InlineQueryResult):
|
||||
"""Represents a link to an mp3 audio file stored on the Telegram
|
||||
servers. By default, this audio file will be sent by the user.
|
||||
Alternatively, you can use input_message_content to send a message with
|
||||
the specified content instead of the audio.
|
||||
"""Represents a link to an mp3 audio file stored on the Telegram servers. By default, this
|
||||
audio file will be sent by the user. Alternatively, you can use input_message_content to send a
|
||||
message with the specified content instead of the audio.
|
||||
|
||||
Attributes:
|
||||
id (str):
|
||||
audio_file_id (str):
|
||||
caption (Optional[str]):
|
||||
reply_markup (Optional[:class:`telegram.InlineKeyboardMarkup`]):
|
||||
input_message_content (Optional[
|
||||
:class:`telegram.input_message_content`]):
|
||||
input_message_content (Optional[:class:`telegram.input_message_content`]):
|
||||
|
||||
Deprecated: 4.0
|
||||
message_text (str): Use :class:`InputTextMessageContent` instead.
|
||||
|
||||
parse_mode (str): Use :class:`InputTextMessageContent` instead.
|
||||
|
||||
disable_web_page_preview (bool): Use :class:`InputTextMessageContent`
|
||||
instead.
|
||||
disable_web_page_preview (bool): Use :class:`InputTextMessageContent` instead.
|
||||
|
||||
Args:
|
||||
audio_file_id (str):
|
||||
**kwargs: Arbitrary keyword arguments.
|
||||
|
||||
Keyword Args:
|
||||
caption (Optional[str]):
|
||||
reply_markup (Optional[:class:`telegram.InlineKeyboardMarkup`]):
|
||||
input_message_content (Optional[
|
||||
:class:`telegram.input_message_content`]):
|
||||
input_message_content (Optional[:class:`telegram.input_message_content`]):
|
||||
**kwargs (dict): Arbitrary keyword arguments.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, id, audio_file_id, reply_markup=None, input_message_content=None, **kwargs):
|
||||
def __init__(self,
|
||||
id,
|
||||
audio_file_id,
|
||||
caption=None,
|
||||
reply_markup=None,
|
||||
input_message_content=None,
|
||||
**kwargs):
|
||||
# Required
|
||||
super(InlineQueryResultCachedAudio, self).__init__('audio', id)
|
||||
self.audio_file_id = audio_file_id
|
||||
|
||||
# Optionals
|
||||
if caption:
|
||||
self.caption = caption
|
||||
if reply_markup:
|
||||
self.reply_markup = reply_markup
|
||||
if input_message_content:
|
||||
|
||||
@@ -16,13 +16,38 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains the classes that represent Telegram
|
||||
InlineQueryResultCachedDocument"""
|
||||
"""This module contains the classes that represent Telegram InlineQueryResultCachedDocument"""
|
||||
|
||||
from telegram import InlineQueryResult, InlineKeyboardMarkup, InputMessageContent
|
||||
|
||||
|
||||
class InlineQueryResultCachedDocument(InlineQueryResult):
|
||||
"""Represents a link to a file stored on the Telegram servers. By default, this file will be
|
||||
sent by the user with an optional caption. Alternatively, you can use input_message_content to
|
||||
send a message with the specified content instead of the file. Currently, only pdf-files and
|
||||
zip archives can be sent using this method.
|
||||
|
||||
Attributes:
|
||||
title (str): Title for the result.
|
||||
document_file_id (str): A valid file identifier for the file.
|
||||
description (Optional[str]): Short description of the result.
|
||||
caption (Optional[str]): Caption of the document to be sent, 0-200 characters.
|
||||
reply_markup (Optional[:class:`telegram.InlineKeyboardMarkup`]): Inline keyboard attached
|
||||
to the message.
|
||||
input_message_content (Optional[:class:`telegram.InputMessageContent`]): Content of the
|
||||
message to be sent instead of the file.
|
||||
|
||||
Args:
|
||||
id (str):
|
||||
title (str):
|
||||
document_file_id (str):
|
||||
description (Optional[str]):
|
||||
caption (Optional[str]):
|
||||
reply_markup (Optional[:class:`telegram.InlineKeyboardMarkup`]):
|
||||
input_message_content (Optional[:class:`telegram.InputMessageContent`]):
|
||||
**kwargs (dict): Arbitrary keyword arguments.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
id,
|
||||
|
||||
@@ -23,6 +23,29 @@ from telegram import InlineQueryResult, InlineKeyboardMarkup, InputMessageConten
|
||||
|
||||
|
||||
class InlineQueryResultCachedGif(InlineQueryResult):
|
||||
"""Represents a link to an animated GIF file stored on the Telegram servers. By default, this
|
||||
animated GIF file will be sent by the user with an optional caption. Alternatively, you can use
|
||||
input_message_content to send a message with specified content instead of the animation.
|
||||
|
||||
Attributes:
|
||||
gif_file_id (str): A valid file identifier for the GIF file.
|
||||
title (Optional[str]): Title for the result.
|
||||
caption (Optional[str]): Caption of the GIF file to be sent, 0-200 characters.
|
||||
reply_markup (Optional[:class:`telegram.InlineKeyboardMarkup`]): Inline keyboard attached
|
||||
to the message.
|
||||
input_message_content (Optional[:class:`telegram.InputMessageContent`]): Content of the
|
||||
message to be sent instead of the GIF animation.
|
||||
|
||||
Args:
|
||||
id (str):
|
||||
gif_file_id (str):
|
||||
title (Optional[str]):
|
||||
caption (Optional[str]):
|
||||
reply_markup (Optional[:class:`telegram.InlineKeyboardMarkup`]):
|
||||
input_message_content (Optional[:class:`telegram.InputMessageContent`]):
|
||||
**kwargs (dict): Arbitrary keyword arguments.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
id,
|
||||
|
||||
@@ -23,6 +23,30 @@ from telegram import InlineQueryResult, InlineKeyboardMarkup, InputMessageConten
|
||||
|
||||
|
||||
class InlineQueryResultCachedMpeg4Gif(InlineQueryResult):
|
||||
"""Represents a link to a video animation (H.264/MPEG-4 AVC video without sound) stored on the
|
||||
Telegram servers. By default, this animated MPEG-4 file will be sent by the user with an
|
||||
optional caption. Alternatively, you can use input_message_content to send a message with the
|
||||
specified content instead of the animation.
|
||||
|
||||
Attributes:
|
||||
mpeg4_file_id (str): A valid file identifier for the MP4 file.
|
||||
title (Optional[str]): Title for the result.
|
||||
caption (Optional[str]): Caption of the MPEG-4 file to be sent, 0-200 characters.
|
||||
reply_markup (Optional[:class:`telegram.InlineKeyboardMarkup`]): Inline keyboard attached
|
||||
to the message.
|
||||
input_message_content (Optional[:class:`telegram.InputMessageContent`]): Content of the
|
||||
message to be sent instead of the video animation
|
||||
|
||||
Args:
|
||||
id (str):
|
||||
mpeg4_file_id (str):
|
||||
title (Optional[str]):
|
||||
caption (Optional[str]):
|
||||
reply_markup (Optional[:class:`telegram.InlineKeyboardMarkup`]):
|
||||
input_message_content (Optional[:class:`telegram.InputMessageContent`]):
|
||||
**kwargs (dict): Arbitrary keyword arguments.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
id,
|
||||
|
||||
@@ -16,13 +16,37 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains the classes that represent Telegram
|
||||
InlineQueryResultPhoto"""
|
||||
"""This module contains the classes that represent Telegram InlineQueryResultPhoto"""
|
||||
|
||||
from telegram import InlineQueryResult, InlineKeyboardMarkup, InputMessageContent
|
||||
|
||||
|
||||
class InlineQueryResultCachedPhoto(InlineQueryResult):
|
||||
"""Represents a link to a photo stored on the Telegram servers. By default, this photo will be
|
||||
sent by the user with an optional caption. Alternatively, you can use input_message_content to
|
||||
send a message with the specified content instead of the photo.
|
||||
|
||||
Attributes:
|
||||
photo_file_id (str): A valid file identifier of the photo.
|
||||
title (Optional[str]): Title for the result.
|
||||
description (Optional[str]): Short description of the result.
|
||||
caption (Optional[str]): Caption of the photo to be sent, 0-200 characters.
|
||||
reply_markup (Optional[:class:`telegram.InlineKeyboardMarkup`]): Inline keyboard attached
|
||||
to the message.
|
||||
input_message_content (Optional[:class:`telegram.InputMessageContent`]): Content of the
|
||||
message to be sent instead of the photo
|
||||
|
||||
Args:
|
||||
id (str):
|
||||
photo_file_id (str):
|
||||
title (Optional[str]):
|
||||
description (Optional[str]):
|
||||
caption (Optional[str]):
|
||||
reply_markup (Optional[:class:`telegram.InlineKeyboardMarkup`]):
|
||||
input_message_content (Optional[:class:`telegram.InputMessageContent`]):
|
||||
**kwargs (dict): Arbitrary keyword arguments.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
id,
|
||||
|
||||
@@ -16,13 +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 the classes that represent Telegram
|
||||
InlineQueryResultCachedSticker"""
|
||||
"""This module contains the classes that represent Telegram InlineQueryResultCachedSticker"""
|
||||
|
||||
from telegram import InlineQueryResult, InlineKeyboardMarkup, InputMessageContent
|
||||
|
||||
|
||||
class InlineQueryResultCachedSticker(InlineQueryResult):
|
||||
"""Represents a link to a sticker stored on the Telegram servers. By default, this sticker will
|
||||
be sent by the user. Alternatively, you can use input_message_content to send a message with
|
||||
the specified content instead of the sticker.
|
||||
|
||||
Attributes:
|
||||
sticker_file_id (str): A valid file identifier of the sticker.
|
||||
reply_markup (Optional[:class:`telegram.InlineKeyboardMarkup`]): Inline keyboard attached
|
||||
to the message.
|
||||
input_message_content (Optional[:class:`telegram.InputMessageContent`]): Content of the
|
||||
message to be sent instead of the sticker.
|
||||
|
||||
Args:
|
||||
id (str):
|
||||
sticker_file_id (str):
|
||||
reply_markup (Optional[:class:`telegram.InlineKeyboardMarkup`]):
|
||||
input_message_content (Optional[:class:`telegram.InputMessageContent`]):
|
||||
**kwargs (dict): Arbitrary keyword arguments.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
id,
|
||||
|
||||
@@ -16,13 +16,37 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains the classes that represent Telegram
|
||||
InlineQueryResultCachedVideo"""
|
||||
"""This module contains the classes that represent Telegram InlineQueryResultCachedVideo"""
|
||||
|
||||
from telegram import InlineQueryResult, InlineKeyboardMarkup, InputMessageContent
|
||||
|
||||
|
||||
class InlineQueryResultCachedVideo(InlineQueryResult):
|
||||
"""Represents a link to a video file stored on the Telegram servers. By default, this video
|
||||
file will be sent by the user with an optional caption. Alternatively, you can use
|
||||
input_message_content to send a message with the specified content instead of the video.
|
||||
|
||||
Attributes:
|
||||
video_file_id (str): A valid file identifier for the video file.
|
||||
title (str): Title for the result.
|
||||
description (Optional[str]): Short description of the result.
|
||||
caption (Optional[str]): Caption of the video to be sent, 0-200 characters.
|
||||
reply_markup (Optional[:class:`telegram.InlineKeyboardMarkup`]): Inline keyboard attached
|
||||
to the message
|
||||
input_message_content (Optional[:class:`telegram.InputMessageContent`]): Content of the
|
||||
message to be sent instead of the video
|
||||
|
||||
Args:
|
||||
id (str):
|
||||
video_file_id (str):
|
||||
title (str):
|
||||
description (Optional[str]):
|
||||
caption (Optional[str]):
|
||||
reply_markup (Optional[:class:`telegram.InlineKeyboardMarkup`]):
|
||||
input_message_content (Optional[:class:`telegram.InputMessageContent`]):
|
||||
**kwargs (dict): Arbitrary keyword arguments.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
id,
|
||||
|
||||
@@ -16,19 +16,41 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains the classes that represent Telegram
|
||||
InlineQueryResultCachedVoice"""
|
||||
"""This module contains the classes that represent Telegram InlineQueryResultCachedVoice"""
|
||||
|
||||
from telegram import InlineQueryResult, InlineKeyboardMarkup, InputMessageContent
|
||||
|
||||
|
||||
class InlineQueryResultCachedVoice(InlineQueryResult):
|
||||
"""Represents a link to a voice message stored on the Telegram servers. By default, this voice
|
||||
message will be sent by the user. Alternatively, you can use input_message_content to send a
|
||||
message with the specified content instead of the voice message.
|
||||
|
||||
Attributes:
|
||||
voice_file_id (str): A valid file identifier for the voice message.
|
||||
title (str): Voice message title.
|
||||
caption (Optional[str]): Caption, 0-200 characters.
|
||||
reply_markup (Optional[:class:`telegram.InlineKeyboardMarkup`]): Inline keyboard attached
|
||||
to the message.
|
||||
input_message_content (Optional[:class:`telegram.InputMessageContent`]): Content of the
|
||||
message to be sent instead of the voice message.
|
||||
|
||||
Args:
|
||||
id (str):
|
||||
voice_file_id (str):
|
||||
title (str):
|
||||
caption (Optional[str]):
|
||||
reply_markup (Optional[:class:`telegram.InlineKeyboardMarkup`]):
|
||||
input_message_content (Optional[:class:`telegram.InputMessageContent`]):
|
||||
**kwargs (dict): Arbitrary keyword arguments.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
id,
|
||||
voice_file_id,
|
||||
title,
|
||||
description=None,
|
||||
caption=None,
|
||||
reply_markup=None,
|
||||
input_message_content=None,
|
||||
**kwargs):
|
||||
@@ -38,8 +60,8 @@ class InlineQueryResultCachedVoice(InlineQueryResult):
|
||||
self.title = title
|
||||
|
||||
# Optionals
|
||||
if description:
|
||||
self.description = description
|
||||
if caption:
|
||||
self.caption = caption
|
||||
if reply_markup:
|
||||
self.reply_markup = reply_markup
|
||||
if input_message_content:
|
||||
|
||||
@@ -16,13 +16,41 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains the classes that represent Telegram
|
||||
InlineQueryResultContact"""
|
||||
"""This module contains the classes that represent Telegram InlineQueryResultContact"""
|
||||
|
||||
from telegram import InlineQueryResult, InlineKeyboardMarkup, InputMessageContent
|
||||
|
||||
|
||||
class InlineQueryResultContact(InlineQueryResult):
|
||||
"""Represents a contact with a phone number. By default, this contact will be sent by the user.
|
||||
Alternatively, you can use input_message_content to send a message with the specified content
|
||||
instead of the contact.
|
||||
|
||||
Attributes:
|
||||
phone_number (str): Contact's phone number.
|
||||
first_name (str): Contact's first name.
|
||||
last_name (Optional[str]): Contact's last name.
|
||||
reply_markup (Optional[:class:`telegram.InlineKeyboardMarkup`]): Inline keyboard attached
|
||||
to the message.
|
||||
input_message_content (Optional[:class:`telegram.InputMessageContent`]): Content of the
|
||||
message to be sent instead of the contact.
|
||||
thumb_url (Optional[str]): Url of the thumbnail for the result.
|
||||
thumb_width (Optional[int]): Thumbnail width.
|
||||
thumb_height (Optional[int]): Thumbnail height.
|
||||
|
||||
Args:
|
||||
id (str):
|
||||
phone_number (str):
|
||||
first_name (str):
|
||||
last_name (Optional[str]):
|
||||
reply_markup (Optional[:class:`telegram.InlineKeyboardMarkup`]):
|
||||
input_message_content (Optional[:class:`telegram.InputMessageContent`]):
|
||||
thumb_url (Optional[str]): Url of the thumbnail for the result.
|
||||
thumb_width (Optional[int]):
|
||||
thumb_height (Optional[int]):
|
||||
**kwargs (dict): Arbitrary keyword arguments.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
id,
|
||||
|
||||
@@ -16,13 +16,46 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains the classes that represent Telegram
|
||||
InlineQueryResultDocument"""
|
||||
"""This module contains the classes that represent Telegram InlineQueryResultDocument"""
|
||||
|
||||
from telegram import InlineQueryResult, InlineKeyboardMarkup, InputMessageContent
|
||||
|
||||
|
||||
class InlineQueryResultDocument(InlineQueryResult):
|
||||
"""Represents a link to a file. By default, this file will be sent by the user with an optional
|
||||
caption. Alternatively, you can use input_message_content to send a message with the specified
|
||||
content instead of the file. Currently, only .PDF and .ZIP files can be sent using this method.
|
||||
|
||||
Attributes:
|
||||
title (str): Title for the result.
|
||||
caption (Optional[str]): Caption of the document to be sent, 0-200 characters.
|
||||
document_url (Optional[str]): A valid URL for the file.
|
||||
mime_type (Optional[str]): Mime type of the content of the file, either "application/pdf"
|
||||
or "application/zip".
|
||||
description (Optional[str]): Short description of the result.
|
||||
reply_markup (Optional[:class:`telegram.InlineKeyboardMarkup`]): Inline keyboard attached
|
||||
to the message.
|
||||
input_message_content (Optional[:class:`telegram.InputMessageContent`]): Content of the
|
||||
message to be sent instead of the file.
|
||||
thumb_url (Optional[str]): URL of the thumbnail (jpeg only) for the file.
|
||||
thumb_width (Optional[int]): Thumbnail width.
|
||||
thumb_height (Optional[int]): Thumbnail height.
|
||||
|
||||
Args:
|
||||
id (str):
|
||||
document_url (str):
|
||||
title (str):
|
||||
mime_type (str):
|
||||
caption (Optional[str]):
|
||||
description (Optional[str]):
|
||||
reply_markup (Optional[:class:`telegram.InlineKeyboardMarkup`]):
|
||||
input_message_content (Optional[:class:`telegram.InputMessageContent`]):
|
||||
thumb_url (Optional[str]):
|
||||
thumb_width (Optional[int]):
|
||||
thumb_height (Optional[int]):
|
||||
**kwargs (dict): Arbitrary keyword arguments.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
id,
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2016
|
||||
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains the classes that represent Telegram
|
||||
InlineQueryResultGame"""
|
||||
|
||||
from telegram import InlineQueryResult, InlineKeyboardMarkup
|
||||
|
||||
|
||||
class InlineQueryResultGame(InlineQueryResult):
|
||||
|
||||
def __init__(self, id, game_short_name, reply_markup=None, **kwargs):
|
||||
# Required
|
||||
super(InlineQueryResultGame, self).__init__('game', id)
|
||||
self.id = id
|
||||
self.game_short_name = game_short_name
|
||||
|
||||
if reply_markup:
|
||||
self.reply_markup = reply_markup
|
||||
|
||||
@staticmethod
|
||||
def de_json(data, bot):
|
||||
data = super(InlineQueryResultGame, InlineQueryResultGame).de_json(data, bot)
|
||||
|
||||
data['reply_markup'] = InlineKeyboardMarkup.de_json(data.get('reply_markup'), bot)
|
||||
|
||||
return InlineQueryResultGame(**data)
|
||||
@@ -23,6 +23,35 @@ from telegram import InlineQueryResult, InlineKeyboardMarkup, InputMessageConten
|
||||
|
||||
|
||||
class InlineQueryResultGif(InlineQueryResult):
|
||||
"""Represents a link to an animated GIF file. By default, this animated GIF file will be sent
|
||||
by the user with optional caption. Alternatively, you can use input_message_content to send a
|
||||
message with the specified content instead of the animation.
|
||||
|
||||
Attributes:
|
||||
gif_url (str): A valid URL for the GIF file. File size must not exceed 1MB.
|
||||
thumb_url (str): URL of the static thumbnail for the result (jpeg or gif).
|
||||
gif_width (Optional[int]): Width of the GIF.
|
||||
gif_height (Optional[int]): Height of the GIF.
|
||||
title (Optional[str]): Title for the result.
|
||||
caption (Optional[str]): Caption of the GIF file to be sent, 0-200 characters.
|
||||
reply_markup (Optional[:class:`telegram.InlineKeyboardMarkup`]): Inline keyboard attached
|
||||
to the message.
|
||||
input_message_content (Optional[:class:`telegram.InputMessageContent`]): Content of the
|
||||
message to be sent instead of the GIF animation.
|
||||
|
||||
Args:
|
||||
id (str):
|
||||
gif_url (str):
|
||||
thumb_url (str):
|
||||
gif_width (Optional[int]):
|
||||
gif_height (Optional[int]):
|
||||
title (Optional[str]):
|
||||
caption (Optional[str]):
|
||||
reply_markup (Optional[:class:`telegram.InlineKeyboardMarkup`]):
|
||||
input_message_content (Optional[:class:`telegram.InputMessageContent`]):
|
||||
**kwargs (dict): Arbitrary keyword arguments.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
id,
|
||||
|
||||
@@ -16,13 +16,42 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains the classes that represent Telegram
|
||||
InlineQueryResultLocation"""
|
||||
"""This module contains the classes that represent Telegram InlineQueryResultLocation"""
|
||||
|
||||
from telegram import InlineQueryResult, InlineKeyboardMarkup, InputMessageContent
|
||||
|
||||
|
||||
class InlineQueryResultLocation(InlineQueryResult):
|
||||
"""Represents a location on a map. By default, the location will be sent by the user.
|
||||
Alternatively, you can use input_message_content to send a message with the specified content
|
||||
instead of the location.
|
||||
|
||||
Attributes:
|
||||
latitude (float): Location latitude in degrees.
|
||||
longitude (float): Location longitude in degrees.
|
||||
title (str): Location title.
|
||||
reply_markup (Optional[:class:`telegram.InlineKeyboardMarkup`]): Inline keyboard attached
|
||||
to the message.
|
||||
input_message_content (Optional[:class:`telegram.InputMessageContent`]): Content of the
|
||||
message to be sent instead of the location.
|
||||
thumb_url (Optional[str]): Url of the thumbnail for the result.
|
||||
thumb_width (Optional[int]): Thumbnail width.
|
||||
thumb_height (Optional[int]): Thumbnail height.
|
||||
|
||||
Args:
|
||||
latitude (float): Location latitude in degrees.
|
||||
longitude (float): Location longitude in degrees.
|
||||
title (str): Location title.
|
||||
reply_markup (Optional[:class:`telegram.InlineKeyboardMarkup`]): Inline keyboard attached
|
||||
to the message.
|
||||
input_message_content (Optional[:class:`telegram.InputMessageContent`]): Content of the
|
||||
message to be sent instead of the location.
|
||||
thumb_url (Optional[str]): Url of the thumbnail for the result.
|
||||
thumb_width (Optional[int]): Thumbnail width.
|
||||
thumb_height (Optional[int]): Thumbnail height.
|
||||
**kwargs (dict): Arbitrary keyword arguments.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
id,
|
||||
|
||||
@@ -16,13 +16,43 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains the classes that represent Telegram
|
||||
InlineQueryResultMpeg4Gif"""
|
||||
"""This module contains the classes that represent Telegram InlineQueryResultMpeg4Gif"""
|
||||
|
||||
from telegram import InlineQueryResult, InlineKeyboardMarkup, InputMessageContent
|
||||
|
||||
|
||||
class InlineQueryResultMpeg4Gif(InlineQueryResult):
|
||||
"""Represents a link to a video animation (H.264/MPEG-4 AVC video without sound). By default,
|
||||
this animated MPEG-4 file will be sent by the user with optional caption. Alternatively, you
|
||||
can use input_message_content to send a message with the specified content instead of the
|
||||
animation.
|
||||
|
||||
Attributes:
|
||||
mpeg4_url (str): A valid URL for the MP4 file. File size must not exceed 1MB.
|
||||
thumb_url (str): URL of the static thumbnail (jpeg or gif) for the result.
|
||||
mpeg4_width (Optional[int]): Video width.
|
||||
mpeg4_height (Optional[int]): Video height.
|
||||
title (Optional[str]): Title for the result.
|
||||
caption (Optional[str]): Caption of the MPEG-4 file to be sent, 0-200 characters.
|
||||
reply_markup (Optional[:class:`telegram.InlineKeyboardMarkup`]): Inline keyboard attached
|
||||
to the message.
|
||||
input_message_content (Optional[:class:`telegram.InputMessageContent`]): Content of the
|
||||
message to be sent instead of the video animation.
|
||||
|
||||
Args:
|
||||
mpeg4_url (str): A valid URL for the MP4 file. File size must not exceed 1MB.
|
||||
thumb_url (str): URL of the static thumbnail (jpeg or gif) for the result.
|
||||
mpeg4_width (Optional[int]): Video width.
|
||||
mpeg4_height (Optional[int]): Video height.
|
||||
title (Optional[str]): Title for the result.
|
||||
caption (Optional[str]): Caption of the MPEG-4 file to be sent, 0-200 characters.
|
||||
reply_markup (Optional[:class:`telegram.InlineKeyboardMarkup`]): Inline keyboard attached
|
||||
to the message.
|
||||
input_message_content (Optional[:class:`telegram.InputMessageContent`]): Content of the
|
||||
message to be sent instead of the video animation.
|
||||
**kwargs (dict): Arbitrary keyword arguments.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
id,
|
||||
|
||||
@@ -16,13 +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 the classes that represent Telegram
|
||||
InlineQueryResultPhoto"""
|
||||
"""This module contains the classes that represent Telegram InlineQueryResultPhoto"""
|
||||
|
||||
from telegram import InlineQueryResult, InlineKeyboardMarkup, InputMessageContent
|
||||
|
||||
|
||||
class InlineQueryResultPhoto(InlineQueryResult):
|
||||
"""Represents a link to a photo. By default, this photo will be sent by the user with optional
|
||||
caption. Alternatively, you can use input_message_content to send a message with the specified
|
||||
content instead of the photo.
|
||||
|
||||
Attributes:
|
||||
photo_url (str): A valid URL of the photo. Photo must be in jpeg format. Photo size must
|
||||
not exceed 5MB.
|
||||
thumb_url (str): URL of the thumbnail for the photo.
|
||||
photo_width (Optional[int]): Width of the photo.
|
||||
photo_height (Optional[int]): Height of the photo.
|
||||
title (Optional[str]): Title for the result.
|
||||
description (Optional[str]): Short description of the result.
|
||||
caption (Optional[str]): Caption of the photo to be sent, 0-200 characters.
|
||||
reply_markup (Optional[:class:`telegram.InlineKeyboardMarkup`]): Inline keyboard attached
|
||||
to the message.
|
||||
input_message_content (Optional[:class:`telegram.InputMessageContent`]): Content of the
|
||||
message to be sent instead of the photo.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
id,
|
||||
|
||||
@@ -29,6 +29,7 @@ class InlineQueryResultVoice(InlineQueryResult):
|
||||
voice_url,
|
||||
title,
|
||||
voice_duration=None,
|
||||
caption=None,
|
||||
reply_markup=None,
|
||||
input_message_content=None,
|
||||
**kwargs):
|
||||
@@ -41,6 +42,8 @@ class InlineQueryResultVoice(InlineQueryResult):
|
||||
# Optional
|
||||
if voice_duration:
|
||||
self.voice_duration = voice_duration
|
||||
if caption:
|
||||
self.caption = caption
|
||||
if reply_markup:
|
||||
self.reply_markup = reply_markup
|
||||
if input_message_content:
|
||||
|
||||
+17
-24
@@ -17,7 +17,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains a object that represents a Telegram InputFile."""
|
||||
"""This module contains an object that represents a Telegram InputFile."""
|
||||
|
||||
try:
|
||||
# python 3
|
||||
@@ -31,12 +31,11 @@ import mimetypes
|
||||
import os
|
||||
import sys
|
||||
|
||||
from future.moves.urllib.request import urlopen
|
||||
|
||||
from telegram import TelegramError
|
||||
|
||||
DEFAULT_MIME_TYPE = 'application/octet-stream'
|
||||
USER_AGENT = 'Python Telegram Bot (https://github.com/python-telegram-bot/python-telegram-bot)'
|
||||
FILE_TYPES = ('audio', 'document', 'photo', 'sticker', 'video', 'voice', 'certificate')
|
||||
|
||||
|
||||
class InputFile(object):
|
||||
@@ -49,32 +48,28 @@ class InputFile(object):
|
||||
if 'audio' in data:
|
||||
self.input_name = 'audio'
|
||||
self.input_file = data.pop('audio')
|
||||
if 'document' in data:
|
||||
elif 'document' in data:
|
||||
self.input_name = 'document'
|
||||
self.input_file = data.pop('document')
|
||||
if 'photo' in data:
|
||||
elif 'photo' in data:
|
||||
self.input_name = 'photo'
|
||||
self.input_file = data.pop('photo')
|
||||
if 'sticker' in data:
|
||||
elif 'sticker' in data:
|
||||
self.input_name = 'sticker'
|
||||
self.input_file = data.pop('sticker')
|
||||
if 'video' in data:
|
||||
elif 'video' in data:
|
||||
self.input_name = 'video'
|
||||
self.input_file = data.pop('video')
|
||||
if 'voice' in data:
|
||||
elif 'voice' in data:
|
||||
self.input_name = 'voice'
|
||||
self.input_file = data.pop('voice')
|
||||
if 'certificate' in data:
|
||||
elif 'certificate' in data:
|
||||
self.input_name = 'certificate'
|
||||
self.input_file = data.pop('certificate')
|
||||
|
||||
if str(self.input_file).startswith('http'):
|
||||
from_url = True
|
||||
self.input_file = urlopen(self.input_file)
|
||||
else:
|
||||
from_url = False
|
||||
raise TelegramError('Unknown inputfile type')
|
||||
|
||||
if hasattr(self.input_file, 'read') or from_url:
|
||||
if hasattr(self.input_file, 'read'):
|
||||
self.filename = None
|
||||
self.input_file_content = self.input_file.read()
|
||||
if 'filename' in data:
|
||||
@@ -83,11 +78,9 @@ class InputFile(object):
|
||||
# on py2.7, pylint fails to understand this properly
|
||||
# pylint: disable=E1101
|
||||
self.filename = os.path.basename(self.input_file.name)
|
||||
elif from_url:
|
||||
self.filename = os.path.basename(self.input_file.url).split('?')[0].split('&')[0]
|
||||
|
||||
try:
|
||||
self.mimetype = InputFile.is_image(self.input_file_content)
|
||||
self.mimetype = self.is_image(self.input_file_content)
|
||||
if not self.filename or '.' not in self.filename:
|
||||
self.filename = self.mimetype.replace('/', '.')
|
||||
except TelegramError:
|
||||
@@ -118,7 +111,8 @@ class InputFile(object):
|
||||
form_boundary = '--' + self.boundary
|
||||
|
||||
# Add data fields
|
||||
for name, value in self.data.items():
|
||||
for name in iter(self.data):
|
||||
value = self.data[name]
|
||||
form.extend([
|
||||
form_boundary, 'Content-Disposition: form-data; name="%s"' % name, '', str(value)
|
||||
])
|
||||
@@ -133,7 +127,7 @@ class InputFile(object):
|
||||
form.append('--' + self.boundary + '--')
|
||||
form.append('')
|
||||
|
||||
return InputFile._parse(form)
|
||||
return self._parse(form)
|
||||
|
||||
@staticmethod
|
||||
def _parse(form):
|
||||
@@ -174,18 +168,17 @@ class InputFile(object):
|
||||
"""Check if the request is a file request.
|
||||
|
||||
Args:
|
||||
data (str): A dict of (str, unicode) key/value pairs
|
||||
data (dict): A dict of (str, unicode) key/value pairs
|
||||
|
||||
Returns:
|
||||
bool
|
||||
"""
|
||||
if data:
|
||||
file_types = ['audio', 'document', 'photo', 'sticker', 'video', 'voice', 'certificate']
|
||||
file_type = [i for i in list(data.keys()) if i in file_types]
|
||||
file_type = [i for i in iter(data) if i in FILE_TYPES]
|
||||
|
||||
if file_type:
|
||||
file_content = data[file_type[0]]
|
||||
|
||||
return hasattr(file_content, 'read') or str(file_content).startswith('http')
|
||||
return hasattr(file_content, 'read')
|
||||
|
||||
return False
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains a object that represents a Telegram KeyboardButton."""
|
||||
"""This module contains an object that represents a Telegram KeyboardButton."""
|
||||
|
||||
from telegram import TelegramObject
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains a object that represents a Telegram Location."""
|
||||
"""This module contains an object that represents a Telegram Location."""
|
||||
|
||||
from telegram import TelegramObject
|
||||
|
||||
|
||||
+115
-33
@@ -17,14 +17,14 @@
|
||||
#
|
||||
# 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 a object that represents a Telegram Message."""
|
||||
"""This module contains an object that represents a Telegram Message."""
|
||||
|
||||
import sys
|
||||
from datetime import datetime
|
||||
from time import mktime
|
||||
|
||||
from telegram import (Audio, Contact, Document, Chat, Location, PhotoSize, Sticker, TelegramObject,
|
||||
User, Video, Voice, Venue, MessageEntity)
|
||||
User, Video, Voice, Venue, MessageEntity, Game)
|
||||
|
||||
|
||||
class Message(TelegramObject):
|
||||
@@ -45,6 +45,7 @@ class Message(TelegramObject):
|
||||
text (str):
|
||||
audio (:class:`telegram.Audio`):
|
||||
document (:class:`telegram.Document`):
|
||||
game (:class:`telegram.Game`):
|
||||
photo (List[:class:`telegram.PhotoSize`]):
|
||||
sticker (:class:`telegram.Sticker`):
|
||||
video (:class:`telegram.Video`):
|
||||
@@ -86,6 +87,7 @@ class Message(TelegramObject):
|
||||
text (Optional[str]):
|
||||
audio (Optional[:class:`telegram.Audio`]):
|
||||
document (Optional[:class:`telegram.Document`]):
|
||||
game (Optional[:class:`telegram.Game`]):
|
||||
photo (Optional[List[:class:`telegram.PhotoSize`]]):
|
||||
sticker (Optional[:class:`telegram.Sticker`]):
|
||||
video (Optional[:class:`telegram.Video`]):
|
||||
@@ -106,41 +108,76 @@ class Message(TelegramObject):
|
||||
bot (Optional[Bot]): The Bot to use for instance methods
|
||||
"""
|
||||
|
||||
def __init__(self, message_id, from_user, date, chat, bot=None, **kwargs):
|
||||
def __init__(self,
|
||||
message_id,
|
||||
from_user,
|
||||
date,
|
||||
chat,
|
||||
forward_from=None,
|
||||
forward_from_chat=None,
|
||||
forward_date=None,
|
||||
reply_to_message=None,
|
||||
edit_date=None,
|
||||
text='',
|
||||
entities=None,
|
||||
audio=None,
|
||||
document=None,
|
||||
photo=None,
|
||||
sticker=None,
|
||||
video=None,
|
||||
voice=None,
|
||||
caption='',
|
||||
contact=None,
|
||||
location=None,
|
||||
venue=None,
|
||||
new_chat_member=None,
|
||||
left_chat_member=None,
|
||||
new_chat_title='',
|
||||
new_chat_photo=None,
|
||||
delete_chat_photo=False,
|
||||
group_chat_created=False,
|
||||
supergroup_chat_created=False,
|
||||
migrate_to_chat_id=0,
|
||||
migrate_from_chat_id=0,
|
||||
channel_chat_created=False,
|
||||
pinned_message=None,
|
||||
bot=None,
|
||||
**kwargs):
|
||||
# Required
|
||||
self.message_id = int(message_id)
|
||||
self.from_user = from_user
|
||||
self.date = date
|
||||
self.chat = chat
|
||||
# Optionals
|
||||
self.forward_from = kwargs.get('forward_from')
|
||||
self.forward_from_chat = kwargs.get('forward_from_chat')
|
||||
self.forward_date = kwargs.get('forward_date')
|
||||
self.reply_to_message = kwargs.get('reply_to_message')
|
||||
self.edit_date = kwargs.get('edit_date')
|
||||
self.text = kwargs.get('text', '')
|
||||
self.entities = kwargs.get('entities', list())
|
||||
self.audio = kwargs.get('audio')
|
||||
self.document = kwargs.get('document')
|
||||
self.photo = kwargs.get('photo')
|
||||
self.sticker = kwargs.get('sticker')
|
||||
self.video = kwargs.get('video')
|
||||
self.voice = kwargs.get('voice')
|
||||
self.caption = kwargs.get('caption', '')
|
||||
self.contact = kwargs.get('contact')
|
||||
self.location = kwargs.get('location')
|
||||
self.venue = kwargs.get('venue')
|
||||
self.new_chat_member = kwargs.get('new_chat_member')
|
||||
self.left_chat_member = kwargs.get('left_chat_member')
|
||||
self.new_chat_title = kwargs.get('new_chat_title', '')
|
||||
self.new_chat_photo = kwargs.get('new_chat_photo')
|
||||
self.delete_chat_photo = bool(kwargs.get('delete_chat_photo', False))
|
||||
self.group_chat_created = bool(kwargs.get('group_chat_created', False))
|
||||
self.supergroup_chat_created = bool(kwargs.get('supergroup_chat_created', False))
|
||||
self.migrate_to_chat_id = int(kwargs.get('migrate_to_chat_id', 0))
|
||||
self.migrate_from_chat_id = int(kwargs.get('migrate_from_chat_id', 0))
|
||||
self.channel_chat_created = bool(kwargs.get('channel_chat_created', False))
|
||||
self.pinned_message = kwargs.get('pinned_message')
|
||||
self.forward_from = forward_from
|
||||
self.forward_from_chat = forward_from_chat
|
||||
self.forward_date = forward_date
|
||||
self.reply_to_message = reply_to_message
|
||||
self.edit_date = edit_date
|
||||
self.text = text
|
||||
self.entities = entities or list()
|
||||
self.audio = audio
|
||||
self.game = kwargs.get('game')
|
||||
self.document = document
|
||||
self.photo = photo
|
||||
self.sticker = sticker
|
||||
self.video = video
|
||||
self.voice = voice
|
||||
self.caption = caption
|
||||
self.contact = contact
|
||||
self.location = location
|
||||
self.venue = venue
|
||||
self.new_chat_member = new_chat_member
|
||||
self.left_chat_member = left_chat_member
|
||||
self.new_chat_title = new_chat_title
|
||||
self.new_chat_photo = new_chat_photo
|
||||
self.delete_chat_photo = bool(delete_chat_photo)
|
||||
self.group_chat_created = bool(group_chat_created)
|
||||
self.supergroup_chat_created = bool(supergroup_chat_created)
|
||||
self.migrate_to_chat_id = int(migrate_to_chat_id)
|
||||
self.migrate_from_chat_id = int(migrate_from_chat_id)
|
||||
self.channel_chat_created = bool(channel_chat_created)
|
||||
self.pinned_message = pinned_message
|
||||
|
||||
self.bot = bot
|
||||
|
||||
@@ -173,6 +210,7 @@ class Message(TelegramObject):
|
||||
data['edit_date'] = Message._fromtimestamp(data.get('edit_date'))
|
||||
data['audio'] = Audio.de_json(data.get('audio'), bot)
|
||||
data['document'] = Document.de_json(data.get('document'), bot)
|
||||
data['game'] = Game.de_json(data.get('game'), bot)
|
||||
data['photo'] = PhotoSize.de_list(data.get('photo'), bot)
|
||||
data['sticker'] = Sticker.de_json(data.get('sticker'), bot)
|
||||
data['video'] = Video.de_json(data.get('video'), bot)
|
||||
@@ -412,6 +450,48 @@ class Message(TelegramObject):
|
||||
disable_notification=disable_notification,
|
||||
message_id=self.message_id)
|
||||
|
||||
def edit_text(self, *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 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)``
|
||||
|
||||
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 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)``
|
||||
|
||||
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 self.bot.edit_message_caption(
|
||||
chat_id=self.chat_id, message_id=self.message_id, *args, **kwargs)
|
||||
|
||||
def parse_entity(self, entity):
|
||||
"""
|
||||
Returns the text from a given :class:`telegram.MessageEntity`.
|
||||
@@ -461,5 +541,7 @@ class Message(TelegramObject):
|
||||
if types is None:
|
||||
types = MessageEntity.ALL_TYPES
|
||||
|
||||
return {entity: self.parse_entity(entity)
|
||||
for entity in self.entities if entity.type in types}
|
||||
return {
|
||||
entity: self.parse_entity(entity)
|
||||
for entity in self.entities if entity.type in types
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains a object that represents a Telegram MessageEntity."""
|
||||
"""This module contains an object that represents a Telegram MessageEntity."""
|
||||
|
||||
from telegram import User, TelegramObject
|
||||
|
||||
@@ -34,14 +34,14 @@ class MessageEntity(TelegramObject):
|
||||
user (Optional[:class:`telegram.User`]):
|
||||
"""
|
||||
|
||||
def __init__(self, type, offset, length, **kwargs):
|
||||
def __init__(self, type, offset, length, url=None, user=None, **kwargs):
|
||||
# Required
|
||||
self.type = type
|
||||
self.offset = offset
|
||||
self.length = length
|
||||
# Optionals
|
||||
self.url = kwargs.get('url')
|
||||
self.user = kwargs.get('user')
|
||||
self.url = url
|
||||
self.user = user
|
||||
|
||||
@staticmethod
|
||||
def de_json(data, bot):
|
||||
@@ -80,5 +80,6 @@ class MessageEntity(TelegramObject):
|
||||
PRE = 'pre'
|
||||
TEXT_LINK = 'text_link'
|
||||
TEXT_MENTION = 'text_mention'
|
||||
ALL_TYPES = [MENTION, HASHTAG, BOT_COMMAND, URL, EMAIL, BOLD, ITALIC, CODE, PRE, TEXT_LINK,
|
||||
TEXT_MENTION]
|
||||
ALL_TYPES = [
|
||||
MENTION, HASHTAG, BOT_COMMAND, URL, EMAIL, BOLD, ITALIC, CODE, PRE, TEXT_LINK, TEXT_MENTION
|
||||
]
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains a object that represents a Telegram
|
||||
"""This module contains an object that represents a Telegram
|
||||
Message Parse Modes."""
|
||||
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains a object that represents a Telegram PhotoSize."""
|
||||
"""This module contains an object that represents a Telegram PhotoSize."""
|
||||
|
||||
from telegram import TelegramObject
|
||||
|
||||
@@ -40,13 +40,13 @@ class PhotoSize(TelegramObject):
|
||||
file_size (Optional[int]):
|
||||
"""
|
||||
|
||||
def __init__(self, file_id, width, height, **kwargs):
|
||||
def __init__(self, file_id, width, height, file_size=0, **kwargs):
|
||||
# Required
|
||||
self.file_id = str(file_id)
|
||||
self.width = int(width)
|
||||
self.height = int(height)
|
||||
# Optionals
|
||||
self.file_size = int(kwargs.get('file_size', 0))
|
||||
self.file_size = int(file_size)
|
||||
|
||||
def __eq__(self, other):
|
||||
if not isinstance(other, self.__class__):
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains a object that represents a Telegram
|
||||
"""This module contains an object that represents a Telegram
|
||||
ReplyKeyboardHide."""
|
||||
|
||||
from telegram import ReplyMarkup
|
||||
@@ -37,11 +37,11 @@ class ReplyKeyboardHide(ReplyMarkup):
|
||||
selective (Optional[bool]):
|
||||
"""
|
||||
|
||||
def __init__(self, hide_keyboard=True, **kwargs):
|
||||
def __init__(self, hide_keyboard=True, selective=False, **kwargs):
|
||||
# Required
|
||||
self.hide_keyboard = bool(hide_keyboard)
|
||||
# Optionals
|
||||
self.selective = bool(kwargs.get('selective', False))
|
||||
self.selective = bool(selective)
|
||||
|
||||
@staticmethod
|
||||
def de_json(data, bot):
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains a object that represents a Telegram
|
||||
"""This module contains an object that represents a Telegram
|
||||
ReplyKeyboardMarkup."""
|
||||
|
||||
from telegram import ReplyMarkup, KeyboardButton
|
||||
@@ -41,13 +41,18 @@ class ReplyKeyboardMarkup(ReplyMarkup):
|
||||
selective (Optional[bool]):
|
||||
"""
|
||||
|
||||
def __init__(self, keyboard, **kwargs):
|
||||
def __init__(self,
|
||||
keyboard,
|
||||
resize_keyboard=False,
|
||||
one_time_keyboard=False,
|
||||
selective=False,
|
||||
**kwargs):
|
||||
# Required
|
||||
self.keyboard = keyboard
|
||||
# Optionals
|
||||
self.resize_keyboard = bool(kwargs.get('resize_keyboard', False))
|
||||
self.one_time_keyboard = bool(kwargs.get('one_time_keyboard', False))
|
||||
self.selective = bool(kwargs.get('selective', False))
|
||||
self.resize_keyboard = bool(resize_keyboard)
|
||||
self.one_time_keyboard = bool(one_time_keyboard)
|
||||
self.selective = bool(selective)
|
||||
|
||||
@staticmethod
|
||||
def de_json(data, bot):
|
||||
|
||||
+5
-5
@@ -16,7 +16,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains a object that represents a Telegram Sticker."""
|
||||
"""This module contains an object that represents a Telegram Sticker."""
|
||||
|
||||
from telegram import PhotoSize, TelegramObject
|
||||
|
||||
@@ -44,15 +44,15 @@ class Sticker(TelegramObject):
|
||||
file_size (Optional[int]):
|
||||
"""
|
||||
|
||||
def __init__(self, file_id, width, height, **kwargs):
|
||||
def __init__(self, file_id, width, height, thumb=None, emoji='', file_size=0, **kwargs):
|
||||
# Required
|
||||
self.file_id = str(file_id)
|
||||
self.width = int(width)
|
||||
self.height = int(height)
|
||||
# Optionals
|
||||
self.thumb = kwargs.get('thumb')
|
||||
self.emoji = kwargs.get('emoji', '')
|
||||
self.file_size = int(kwargs.get('file_size', 0))
|
||||
self.thumb = thumb
|
||||
self.emoji = emoji
|
||||
self.file_size = int(file_size)
|
||||
|
||||
@staticmethod
|
||||
def de_json(data, bot):
|
||||
|
||||
+14
-7
@@ -16,7 +16,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains a object that represents a Telegram Update."""
|
||||
"""This module contains an object that represents a Telegram Update."""
|
||||
|
||||
from telegram import (Message, TelegramObject, InlineQuery, ChosenInlineResult, CallbackQuery)
|
||||
|
||||
@@ -44,15 +44,22 @@ class Update(TelegramObject):
|
||||
callback_query (Optional[:class:`telegram.CallbackQuery`]):
|
||||
"""
|
||||
|
||||
def __init__(self, update_id, **kwargs):
|
||||
def __init__(self,
|
||||
update_id,
|
||||
message=None,
|
||||
edited_message=None,
|
||||
inline_query=None,
|
||||
chosen_inline_result=None,
|
||||
callback_query=None,
|
||||
**kwargs):
|
||||
# Required
|
||||
self.update_id = int(update_id)
|
||||
# Optionals
|
||||
self.message = kwargs.get('message')
|
||||
self.edited_message = kwargs.get('edited_message')
|
||||
self.inline_query = kwargs.get('inline_query')
|
||||
self.chosen_inline_result = kwargs.get('chosen_inline_result')
|
||||
self.callback_query = kwargs.get('callback_query')
|
||||
self.message = message
|
||||
self.edited_message = edited_message
|
||||
self.inline_query = inline_query
|
||||
self.chosen_inline_result = chosen_inline_result
|
||||
self.callback_query = callback_query
|
||||
|
||||
@staticmethod
|
||||
def de_json(data, bot):
|
||||
|
||||
+5
-5
@@ -17,7 +17,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains a object that represents a Telegram User."""
|
||||
"""This module contains an object that represents a Telegram User."""
|
||||
|
||||
from telegram import TelegramObject
|
||||
|
||||
@@ -44,14 +44,14 @@ class User(TelegramObject):
|
||||
bot (Optional[Bot]): The Bot to use for instance methods
|
||||
"""
|
||||
|
||||
def __init__(self, id, first_name, bot=None, **kwargs):
|
||||
def __init__(self, id, first_name, type='', last_name='', username='', bot=None, **kwargs):
|
||||
# Required
|
||||
self.id = int(id)
|
||||
self.first_name = first_name
|
||||
# Optionals
|
||||
self.type = kwargs.get('type', '')
|
||||
self.last_name = kwargs.get('last_name', '')
|
||||
self.username = kwargs.get('username', '')
|
||||
self.type = type
|
||||
self.last_name = last_name
|
||||
self.username = username
|
||||
|
||||
self.bot = bot
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains a object that represents a Telegram
|
||||
"""This module contains an object that represents a Telegram
|
||||
UserProfilePhotos."""
|
||||
|
||||
from telegram import PhotoSize, TelegramObject
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2016
|
||||
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
""" This module contains helper functions """
|
||||
|
||||
|
||||
def extract_chat_and_user(update):
|
||||
user = None
|
||||
chat = None
|
||||
|
||||
if update.message:
|
||||
user = update.message.from_user
|
||||
chat = update.message.chat
|
||||
|
||||
elif update.edited_message:
|
||||
user = update.edited_message.from_user
|
||||
chat = update.edited_message.chat
|
||||
|
||||
elif update.inline_query:
|
||||
user = update.inline_query.from_user
|
||||
|
||||
elif update.chosen_inline_result:
|
||||
user = update.chosen_inline_result.from_user
|
||||
|
||||
elif update.callback_query:
|
||||
user = update.callback_query.from_user
|
||||
chat = update.callback_query.message.chat if update.callback_query.message else None
|
||||
|
||||
return chat, user
|
||||
@@ -31,7 +31,8 @@ import urllib3
|
||||
from urllib3.connection import HTTPConnection
|
||||
|
||||
from telegram import (InputFile, TelegramError)
|
||||
from telegram.error import Unauthorized, NetworkError, TimedOut, BadRequest, ChatMigrated
|
||||
from telegram.error import Unauthorized, NetworkError, TimedOut, BadRequest, ChatMigrated, \
|
||||
RetryAfter
|
||||
|
||||
logging.getLogger('urllib3').setLevel(logging.WARNING)
|
||||
|
||||
@@ -105,6 +106,9 @@ class Request(object):
|
||||
migrate_to_chat_id = parameters.get('migrate_to_chat_id')
|
||||
if migrate_to_chat_id:
|
||||
raise ChatMigrated(migrate_to_chat_id)
|
||||
retry_after = parameters.get('retry_after')
|
||||
if retry_after:
|
||||
raise RetryAfter(retry_after)
|
||||
if description:
|
||||
return description
|
||||
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains a object that represents a Telegram Venue."""
|
||||
"""This module contains an object that represents a Telegram Venue."""
|
||||
|
||||
from telegram import TelegramObject, Location
|
||||
|
||||
|
||||
+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.1.0'
|
||||
__version__ = '5.2.0'
|
||||
|
||||
+13
-5
@@ -16,7 +16,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains a object that represents a Telegram Video."""
|
||||
"""This module contains an object that represents a Telegram Video."""
|
||||
|
||||
from telegram import PhotoSize, TelegramObject
|
||||
|
||||
@@ -46,16 +46,24 @@ class Video(TelegramObject):
|
||||
file_size (Optional[int]):
|
||||
"""
|
||||
|
||||
def __init__(self, file_id, width, height, duration, **kwargs):
|
||||
def __init__(self,
|
||||
file_id,
|
||||
width,
|
||||
height,
|
||||
duration,
|
||||
thumb=None,
|
||||
mime_type='',
|
||||
file_size=0,
|
||||
**kwargs):
|
||||
# Required
|
||||
self.file_id = str(file_id)
|
||||
self.width = int(width)
|
||||
self.height = int(height)
|
||||
self.duration = int(duration)
|
||||
# Optionals
|
||||
self.thumb = kwargs.get('thumb')
|
||||
self.mime_type = str(kwargs.get('mime_type', ''))
|
||||
self.file_size = int(kwargs.get('file_size', 0))
|
||||
self.thumb = thumb
|
||||
self.mime_type = str(mime_type)
|
||||
self.file_size = int(file_size)
|
||||
|
||||
@staticmethod
|
||||
def de_json(data, bot):
|
||||
|
||||
+6
-6
@@ -16,7 +16,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains a object that represents a Telegram Voice."""
|
||||
"""This module contains an object that represents a Telegram Voice."""
|
||||
|
||||
from telegram import TelegramObject
|
||||
|
||||
@@ -32,21 +32,21 @@ class Voice(TelegramObject):
|
||||
|
||||
Args:
|
||||
file_id (str):
|
||||
duration (Optional[int]):
|
||||
**kwargs: Arbitrary keyword arguments.
|
||||
|
||||
Keyword Args:
|
||||
duration (Optional[int]):
|
||||
mime_type (Optional[str]):
|
||||
file_size (Optional[int]):
|
||||
"""
|
||||
|
||||
def __init__(self, file_id, **kwargs):
|
||||
def __init__(self, file_id, duration, mime_type='', file_size=0, **kwargs):
|
||||
# Required
|
||||
self.file_id = str(file_id)
|
||||
self.duration = int(duration)
|
||||
# Optionals
|
||||
self.duration = int(kwargs.get('duration', 0))
|
||||
self.mime_type = str(kwargs.get('mime_type', ''))
|
||||
self.file_size = int(kwargs.get('file_size', 0))
|
||||
self.mime_type = str(mime_type)
|
||||
self.file_size = int(file_size)
|
||||
|
||||
@staticmethod
|
||||
def de_json(data, bot):
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2016
|
||||
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram WebhookInfo."""
|
||||
|
||||
from telegram import TelegramObject
|
||||
|
||||
|
||||
class WebhookInfo(TelegramObject):
|
||||
"""This object represents a Telegram WebhookInfo.
|
||||
|
||||
Attributes:
|
||||
url (str): Webhook URL, may be empty if webhook is not set up.
|
||||
has_custom_certificate (bool):
|
||||
pending_update_count (int):
|
||||
last_error_date (int):
|
||||
last_error_message (str):
|
||||
|
||||
Args:
|
||||
url (str): Webhook URL, may be empty if webhook is not set up.
|
||||
has_custom_certificate (bool):
|
||||
pending_update_count (int):
|
||||
last_error_date (Optional[int]):
|
||||
last_error_message (Optional[str]):
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, url, has_custom_certificate, pending_update_count, **kwargs):
|
||||
# Required
|
||||
self.url = url
|
||||
self.has_custom_certificate = has_custom_certificate
|
||||
self.pending_update_count = pending_update_count
|
||||
self.last_error_date = kwargs.get('last_error_date', '')
|
||||
self.last_error_message = kwargs.get('last_error_message', '')
|
||||
|
||||
@staticmethod
|
||||
def de_json(data, bot):
|
||||
"""
|
||||
Args:
|
||||
data (dict):
|
||||
bot (telegram.Bot):
|
||||
|
||||
Returns:
|
||||
telegram.WebhookInfo:
|
||||
|
||||
"""
|
||||
if not data:
|
||||
return None
|
||||
|
||||
return WebhookInfo(**data)
|
||||
+1
-1
@@ -16,7 +16,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 a object that represents a Base class for tests"""
|
||||
"""This module contains an object that represents a Base class for tests"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 36 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 40 KiB |
+39
-10
@@ -16,7 +16,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 a object that represents Tests for Telegram Audio"""
|
||||
"""This module contains an object that represents Tests for Telegram Audio"""
|
||||
|
||||
import sys
|
||||
import unittest
|
||||
@@ -40,6 +40,7 @@ class AudioTest(BaseTest, unittest.TestCase):
|
||||
self.duration = 4
|
||||
self.performer = 'Leandro Toledo'
|
||||
self.title = 'Teste'
|
||||
self.caption = "Test audio"
|
||||
self.mime_type = 'audio/mpeg'
|
||||
self.file_size = 28232
|
||||
|
||||
@@ -48,6 +49,7 @@ class AudioTest(BaseTest, unittest.TestCase):
|
||||
'duration': self.duration,
|
||||
'performer': self.performer,
|
||||
'title': self.title,
|
||||
'caption': self.caption,
|
||||
'mime_type': self.mime_type,
|
||||
'file_size': self.file_size
|
||||
}
|
||||
@@ -57,6 +59,8 @@ class AudioTest(BaseTest, unittest.TestCase):
|
||||
def test_send_audio_required_args_only(self):
|
||||
message = self._bot.sendAudio(self._chat_id, self.audio_file)
|
||||
|
||||
self.assertEqual(message.caption, '')
|
||||
|
||||
audio = message.audio
|
||||
|
||||
self.assertTrue(isinstance(audio.file_id, str))
|
||||
@@ -76,9 +80,12 @@ class AudioTest(BaseTest, unittest.TestCase):
|
||||
duration=self.duration,
|
||||
performer=self.performer,
|
||||
title=self.title,
|
||||
caption=self.caption,
|
||||
mime_type=self.mime_type,
|
||||
file_size=self.file_size)
|
||||
|
||||
self.assertEqual(message.caption, self.caption)
|
||||
|
||||
audio = message.audio
|
||||
|
||||
self.assertTrue(isinstance(audio.file_id, str))
|
||||
@@ -97,7 +104,10 @@ class AudioTest(BaseTest, unittest.TestCase):
|
||||
audio=self.audio_file,
|
||||
duration=self.duration,
|
||||
performer=self.performer,
|
||||
title=self.title)
|
||||
title=self.title,
|
||||
caption=self.caption)
|
||||
|
||||
self.assertEqual(message.caption, self.caption)
|
||||
|
||||
audio = message.audio
|
||||
|
||||
@@ -118,8 +128,11 @@ class AudioTest(BaseTest, unittest.TestCase):
|
||||
duration=self.duration,
|
||||
performer=self.performer,
|
||||
title=self.title,
|
||||
caption=self.caption,
|
||||
filename='telegram_custom.mp3')
|
||||
|
||||
self.assertEqual(message.caption, self.caption)
|
||||
|
||||
audio = message.audio
|
||||
|
||||
self.assertTrue(isinstance(audio.file_id, str))
|
||||
@@ -134,19 +147,32 @@ class AudioTest(BaseTest, unittest.TestCase):
|
||||
@timeout(10)
|
||||
def test_send_audio_mp3_url_file(self):
|
||||
message = self._bot.sendAudio(
|
||||
chat_id=self._chat_id,
|
||||
audio=self.audio_file_url,
|
||||
duration=self.duration,
|
||||
performer=self.performer,
|
||||
title=self.title)
|
||||
chat_id=self._chat_id, audio=self.audio_file_url, duration=self.duration)
|
||||
|
||||
audio = message.audio
|
||||
|
||||
self.assertTrue(isinstance(audio.file_id, str))
|
||||
self.assertNotEqual(audio.file_id, '')
|
||||
self.assertEqual(audio.duration, self.duration)
|
||||
self.assertEqual(audio.mime_type, self.mime_type)
|
||||
self.assertEqual(audio.file_size, self.file_size)
|
||||
|
||||
@flaky(3, 1)
|
||||
@timeout(10)
|
||||
def test_send_audio_mp3_url_file_with_caption(self):
|
||||
message = self._bot.sendAudio(
|
||||
chat_id=self._chat_id,
|
||||
audio=self.audio_file_url,
|
||||
duration=self.duration,
|
||||
caption=self.caption)
|
||||
|
||||
self.assertEqual(message.caption, self.caption)
|
||||
|
||||
audio = message.audio
|
||||
|
||||
self.assertTrue(isinstance(audio.file_id, str))
|
||||
self.assertNotEqual(audio.file_id, '')
|
||||
self.assertEqual(audio.duration, self.duration)
|
||||
self.assertEqual(audio.performer, self.performer)
|
||||
self.assertEqual(audio.title, self.title)
|
||||
self.assertEqual(audio.mime_type, self.mime_type)
|
||||
self.assertEqual(audio.file_size, self.file_size)
|
||||
|
||||
@@ -158,7 +184,10 @@ class AudioTest(BaseTest, unittest.TestCase):
|
||||
audio=self.audio_file_id,
|
||||
duration=self.duration,
|
||||
performer=self.performer,
|
||||
title=self.title)
|
||||
title=self.title,
|
||||
caption=self.caption)
|
||||
|
||||
self.assertEqual(message.caption, self.caption)
|
||||
|
||||
audio = message.audio
|
||||
|
||||
|
||||
+93
-1
@@ -17,11 +17,12 @@
|
||||
#
|
||||
# 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 a object that represents Tests for Telegram Bot"""
|
||||
"""This module contains an object that represents Tests for Telegram Bot"""
|
||||
|
||||
import io
|
||||
import re
|
||||
from datetime import datetime
|
||||
import time
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
@@ -30,6 +31,7 @@ from flaky import flaky
|
||||
sys.path.append('.')
|
||||
|
||||
import telegram
|
||||
from telegram.error import BadRequest
|
||||
from tests.base import BaseTest, timeout
|
||||
|
||||
|
||||
@@ -66,6 +68,17 @@ class BotTest(BaseTest, unittest.TestCase):
|
||||
self.assertEqual(message.text, u'Моё судно на воздушной подушке полно угрей')
|
||||
self.assertTrue(isinstance(message.date, datetime))
|
||||
|
||||
@flaky(3, 1)
|
||||
@timeout(10)
|
||||
def test_sendMessage_no_web_page_preview(self):
|
||||
message = self._bot.sendMessage(
|
||||
chat_id=self._chat_id,
|
||||
text='Моё судно на воздушной подушке полно угрей',
|
||||
disable_web_page_preview=True)
|
||||
|
||||
self.assertTrue(self.is_json(message.to_json()))
|
||||
self.assertEqual(message.text, u'Моё судно на воздушной подушке полно угрей')
|
||||
|
||||
@flaky(3, 1)
|
||||
@timeout(10)
|
||||
def testGetUpdates(self):
|
||||
@@ -158,6 +171,17 @@ class BotTest(BaseTest, unittest.TestCase):
|
||||
self.assertTrue(self.is_json(message.to_json()))
|
||||
self.assertEqual(message.photo[0].file_size, 1451)
|
||||
|
||||
@flaky(3, 1)
|
||||
@timeout(10)
|
||||
def testSendGame(self):
|
||||
game_short_name = 'python_telegram_bot_test_game'
|
||||
message = self._bot.sendGame(game_short_name=game_short_name, chat_id=self._chat_id)
|
||||
|
||||
self.assertTrue(self.is_json(message.to_json()))
|
||||
self.assertEqual(message.game.description, 'This is a test game for python-telegram-bot.')
|
||||
self.assertEqual(message.game.animation.file_id, 'BQADAQADKwIAAvjAuQABozciVqhFDO0C')
|
||||
self.assertEqual(message.game.photo[0].file_size, 851)
|
||||
|
||||
@flaky(3, 1)
|
||||
@timeout(10)
|
||||
def testSendChatAction(self):
|
||||
@@ -171,6 +195,13 @@ class BotTest(BaseTest, unittest.TestCase):
|
||||
self.assertTrue(self.is_json(upf.to_json()))
|
||||
self.assertEqual(upf.photos[0][0].file_size, 12421)
|
||||
|
||||
@flaky(3, 1)
|
||||
@timeout(10)
|
||||
def test_get_one_user_profile_photo(self):
|
||||
upf = self._bot.getUserProfilePhotos(user_id=self._chat_id, offset=0)
|
||||
self.assertTrue(self.is_json(upf.to_json()))
|
||||
self.assertEqual(upf.photos[0][0].file_size, 12421)
|
||||
|
||||
def _test_invalid_token(self, token):
|
||||
self.assertRaisesRegexp(telegram.error.InvalidToken, 'Invalid token', telegram.Bot, token)
|
||||
|
||||
@@ -255,6 +286,46 @@ class BotTest(BaseTest, unittest.TestCase):
|
||||
self.assertEqual(chat_member.status, "administrator")
|
||||
self._testUserEqualsBot(bot)
|
||||
|
||||
@flaky(3, 1)
|
||||
@timeout(10)
|
||||
def test_get_webhook_info(self):
|
||||
url = 'https://python-telegram-bot.org/test/webhook'
|
||||
self._bot.set_webhook(url)
|
||||
info = self._bot.getWebhookInfo()
|
||||
self._bot.set_webhook('')
|
||||
self.assertEqual(url, info.url)
|
||||
|
||||
@flaky(3, 1)
|
||||
@timeout(10)
|
||||
def test_set_game_score(self):
|
||||
# We need a game to set the score for
|
||||
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),
|
||||
chat_id=game.chat_id,
|
||||
message_id=game.message_id,
|
||||
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.assertNotEqual(message.game.text, game.game.text)
|
||||
|
||||
@flaky(3, 1)
|
||||
@timeout(10)
|
||||
def test_set_game_score_too_low_score(self):
|
||||
# We need a game to set the score for
|
||||
game_short_name = 'python_telegram_bot_test_game'
|
||||
game = self._bot.sendGame(game_short_name=game_short_name, chat_id=self._chat_id)
|
||||
|
||||
with self.assertRaises(BadRequest):
|
||||
self._bot.set_game_score(
|
||||
user_id=self._chat_id, score=100, chat_id=game.chat_id, message_id=game.message_id)
|
||||
|
||||
def _testUserEqualsBot(self, user):
|
||||
"""Tests if user is our trusty @PythonTelegramBot."""
|
||||
self.assertEqual(user.id, 133505823)
|
||||
@@ -263,6 +334,27 @@ class BotTest(BaseTest, unittest.TestCase):
|
||||
self.assertEqual(user.username, 'PythonTelegramBot')
|
||||
self.assertEqual(user.name, '@PythonTelegramBot')
|
||||
|
||||
@flaky(3, 1)
|
||||
@timeout(10)
|
||||
def test_info(self):
|
||||
# tests the Bot.info decorator and associated funcs
|
||||
self.assertEqual(self._bot.id, 133505823)
|
||||
self.assertEqual(self._bot.first_name, 'PythonTelegramBot')
|
||||
self.assertEqual(self._bot.last_name, '')
|
||||
self.assertEqual(self._bot.username, 'PythonTelegramBot')
|
||||
self.assertEqual(self._bot.name, '@PythonTelegramBot')
|
||||
|
||||
@flaky(3, 1)
|
||||
@timeout(10)
|
||||
def test_send_contact(self):
|
||||
phone = '+3-54-5445445'
|
||||
name = 'name'
|
||||
last = 'last'
|
||||
message = self._bot.send_contact(self._chat_id, phone, name, last)
|
||||
self.assertEqual(phone.replace('-', ''), message.contact.phone_number)
|
||||
self.assertEqual(name, message.contact.first_name)
|
||||
self.assertEqual(last, message.contact.last_name)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
+10
-2
@@ -16,7 +16,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 a object that represents Tests for Telegram Chat"""
|
||||
"""This module contains an object that represents Tests for Telegram Chat"""
|
||||
|
||||
import unittest
|
||||
import sys
|
||||
@@ -36,8 +36,14 @@ class ChatTest(BaseTest, unittest.TestCase):
|
||||
self.id = -28767330
|
||||
self.title = 'ToledosPalaceBot - Group'
|
||||
self.type = 'group'
|
||||
self.all_members_are_admins = False
|
||||
|
||||
self.json_dict = {'id': self.id, 'title': self.title, 'type': self.type}
|
||||
self.json_dict = {
|
||||
'id': self.id,
|
||||
'title': self.title,
|
||||
'type': self.type,
|
||||
'all_members_are_admins': self.all_members_are_admins
|
||||
}
|
||||
|
||||
def test_group_chat_de_json_empty_json(self):
|
||||
group_chat = telegram.Chat.de_json({}, self._bot)
|
||||
@@ -50,6 +56,7 @@ class ChatTest(BaseTest, unittest.TestCase):
|
||||
self.assertEqual(group_chat.id, self.id)
|
||||
self.assertEqual(group_chat.title, self.title)
|
||||
self.assertEqual(group_chat.type, self.type)
|
||||
self.assertEqual(group_chat.all_members_are_admins, self.all_members_are_admins)
|
||||
|
||||
def test_group_chat_to_json(self):
|
||||
group_chat = telegram.Chat.de_json(self.json_dict, self._bot)
|
||||
@@ -63,6 +70,7 @@ class ChatTest(BaseTest, unittest.TestCase):
|
||||
self.assertEqual(group_chat['id'], self.id)
|
||||
self.assertEqual(group_chat['title'], self.title)
|
||||
self.assertEqual(group_chat['type'], self.type)
|
||||
self.assertEqual(group_chat['all_members_are_admins'], self.all_members_are_admins)
|
||||
|
||||
@flaky(3, 1)
|
||||
def test_send_action(self):
|
||||
|
||||
@@ -16,7 +16,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 a object that represents Tests for Telegram
|
||||
"""This module contains an object that represents Tests for Telegram
|
||||
ChosenInlineResult"""
|
||||
|
||||
import sys
|
||||
|
||||
@@ -16,7 +16,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 a object that represents Tests for Telegram Contact"""
|
||||
"""This module contains an object that represents Tests for Telegram Contact"""
|
||||
|
||||
import unittest
|
||||
import sys
|
||||
|
||||
@@ -18,7 +18,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 a object that represents Tests for ConversationHandler
|
||||
This module contains an object that represents Tests for ConversationHandler
|
||||
"""
|
||||
import logging
|
||||
import sys
|
||||
@@ -66,14 +66,17 @@ class ConversationHandlerTest(BaseTest, unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.current_state = dict()
|
||||
self.entry_points = [CommandHandler('start', self.start)]
|
||||
self.states = {self.THIRSTY: [CommandHandler('brew', self.brew),
|
||||
CommandHandler('wait', self.start)],
|
||||
self.BREWING: [CommandHandler('pourCoffee', self.drink)],
|
||||
self.DRINKING: [CommandHandler('startCoding', self.code),
|
||||
CommandHandler('drinkMore', self.drink)],
|
||||
self.CODING: [CommandHandler('keepCoding', self.code),
|
||||
CommandHandler('gettingThirsty', self.start),
|
||||
CommandHandler('drinkMore', self.drink)],}
|
||||
self.states = {
|
||||
self.THIRSTY: [CommandHandler('brew', self.brew), CommandHandler('wait', self.start)],
|
||||
self.BREWING: [CommandHandler('pourCoffee', self.drink)],
|
||||
self.DRINKING:
|
||||
[CommandHandler('startCoding', self.code), CommandHandler('drinkMore', self.drink)],
|
||||
self.CODING: [
|
||||
CommandHandler('keepCoding', self.code),
|
||||
CommandHandler('gettingThirsty', self.start),
|
||||
CommandHandler('drinkMore', self.drink)
|
||||
],
|
||||
}
|
||||
self.fallbacks = [CommandHandler('eat', self.start)]
|
||||
|
||||
def _setup_updater(self, *args, **kwargs):
|
||||
|
||||
@@ -16,7 +16,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 a object that represents Tests for Telegram Document"""
|
||||
"""This module contains an object that represents Tests for Telegram Document"""
|
||||
|
||||
import sys
|
||||
import unittest
|
||||
@@ -37,10 +37,12 @@ class DocumentTest(BaseTest, unittest.TestCase):
|
||||
self.document_file = open('tests/data/telegram.png', 'rb')
|
||||
self.document_file_id = 'BQADAQADpAADHyP1B04ipZxJTe2BAg'
|
||||
self.document_file_url = 'https://raw.githubusercontent.com/python-telegram-bot/python-telegram-bot/master/tests/data/telegram.gif'
|
||||
self.thumb = {'width': 90,
|
||||
'height': 90,
|
||||
'file_id': 'BQADAQADoQADHyP1B0mzJMVyzcB0Ag',
|
||||
'file_size': 2364}
|
||||
self.thumb = {
|
||||
'width': 90,
|
||||
'height': 90,
|
||||
'file_id': 'BQADAQADoQADHyP1B0mzJMVyzcB0Ag',
|
||||
'file_size': 2364
|
||||
}
|
||||
self.file_name = 'telegram.png'
|
||||
self.mime_type = 'image/png'
|
||||
self.file_size = 12948
|
||||
@@ -56,7 +58,7 @@ class DocumentTest(BaseTest, unittest.TestCase):
|
||||
@flaky(3, 1)
|
||||
@timeout(10)
|
||||
def test_send_document_png_file(self):
|
||||
message = self._bot.sendDocument(self._chat_id, self.document_file)
|
||||
message = self._bot.sendDocument(self._chat_id, self.document_file, caption='caption text')
|
||||
|
||||
document = message.document
|
||||
|
||||
|
||||
+1
-1
@@ -16,7 +16,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 a object that represents Tests for Telegram File"""
|
||||
"""This module contains an object that represents Tests for Telegram File"""
|
||||
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
+70
-7
@@ -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 a object that represents Tests for MessageHandler.Filters
|
||||
This module contains an object that represents Tests for Filters for use with MessageHandler.
|
||||
"""
|
||||
|
||||
import sys
|
||||
@@ -28,7 +28,7 @@ import functools
|
||||
sys.path.append('.')
|
||||
|
||||
from telegram import Message, User, Chat, MessageEntity
|
||||
from telegram.ext import Filters
|
||||
from telegram.ext import Filters, BaseFilter
|
||||
from tests.base import BaseTest
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ class FiltersTest(BaseTest, unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.message = Message(0, User(0, "Testuser"), datetime.now(), Chat(0, 'private'))
|
||||
self.e = functools.partial(MessageEntity, offset=0, length=0)
|
||||
|
||||
def test_filters_text(self):
|
||||
self.message.text = 'test'
|
||||
@@ -104,6 +105,12 @@ class FiltersTest(BaseTest, unittest.TestCase):
|
||||
self.message.venue = None
|
||||
self.assertFalse(Filters.venue(self.message))
|
||||
|
||||
def test_filters_game(self):
|
||||
self.message.game = 'test'
|
||||
self.assertTrue(Filters.game(self.message))
|
||||
self.message.game = None
|
||||
self.assertFalse(Filters.game(self.message))
|
||||
|
||||
def test_filters_status_update(self):
|
||||
self.assertFalse(Filters.status_update(self.message))
|
||||
|
||||
@@ -152,20 +159,76 @@ class FiltersTest(BaseTest, unittest.TestCase):
|
||||
self.message.pinned_message = None
|
||||
|
||||
def test_entities_filter(self):
|
||||
e = functools.partial(MessageEntity, offset=0, length=0)
|
||||
|
||||
self.message.entities = [e(MessageEntity.MENTION)]
|
||||
self.message.entities = [self.e(MessageEntity.MENTION)]
|
||||
self.assertTrue(Filters.entity(MessageEntity.MENTION)(self.message))
|
||||
|
||||
self.message.entities = []
|
||||
self.assertFalse(Filters.entity(MessageEntity.MENTION)(self.message))
|
||||
|
||||
self.message.entities = [e(MessageEntity.BOLD)]
|
||||
self.message.entities = [self.e(MessageEntity.BOLD)]
|
||||
self.assertFalse(Filters.entity(MessageEntity.MENTION)(self.message))
|
||||
|
||||
self.message.entities = [e(MessageEntity.BOLD), e(MessageEntity.MENTION)]
|
||||
self.message.entities = [self.e(MessageEntity.BOLD), self.e(MessageEntity.MENTION)]
|
||||
self.assertTrue(Filters.entity(MessageEntity.MENTION)(self.message))
|
||||
|
||||
def test_and_filters(self):
|
||||
self.message.text = 'test'
|
||||
self.message.forward_date = True
|
||||
self.assertTrue((Filters.text & Filters.forwarded)(self.message))
|
||||
self.message.text = '/test'
|
||||
self.assertFalse((Filters.text & Filters.forwarded)(self.message))
|
||||
self.message.text = 'test'
|
||||
self.message.forward_date = None
|
||||
self.assertFalse((Filters.text & Filters.forwarded)(self.message))
|
||||
|
||||
self.message.text = 'test'
|
||||
self.message.forward_date = True
|
||||
self.message.entities = [self.e(MessageEntity.MENTION)]
|
||||
self.assertTrue((Filters.text & Filters.forwarded & Filters.entity(MessageEntity.MENTION))(
|
||||
self.message))
|
||||
self.message.entities = [self.e(MessageEntity.BOLD)]
|
||||
self.assertFalse((Filters.text & Filters.forwarded & Filters.entity(MessageEntity.MENTION)
|
||||
)(self.message))
|
||||
|
||||
def test_or_filters(self):
|
||||
self.message.text = 'test'
|
||||
self.assertTrue((Filters.text | Filters.status_update)(self.message))
|
||||
self.message.group_chat_created = True
|
||||
self.assertTrue((Filters.text | Filters.status_update)(self.message))
|
||||
self.message.text = None
|
||||
self.assertTrue((Filters.text | Filters.status_update)(self.message))
|
||||
self.message.group_chat_created = False
|
||||
self.assertFalse((Filters.text | Filters.status_update)(self.message))
|
||||
|
||||
def test_and_or_filters(self):
|
||||
self.message.text = 'test'
|
||||
self.message.forward_date = True
|
||||
self.assertTrue((Filters.text & (Filters.forwarded | Filters.entity(MessageEntity.MENTION))
|
||||
)(self.message))
|
||||
self.message.forward_date = False
|
||||
self.assertFalse((Filters.text & (Filters.forwarded | Filters.entity(MessageEntity.MENTION)
|
||||
))(self.message))
|
||||
self.message.entities = [self.e(MessageEntity.MENTION)]
|
||||
self.assertTrue((Filters.text & (Filters.forwarded | Filters.entity(MessageEntity.MENTION))
|
||||
)(self.message))
|
||||
|
||||
self.assertRegexpMatches(
|
||||
str((Filters.text & (Filters.forwarded | Filters.entity(MessageEntity.MENTION)))),
|
||||
r"<telegram.ext.filters.MergedFilter consisting of <telegram.ext.filters.(Filters.)?_"
|
||||
r"Text object at .*?> and <telegram.ext.filters.MergedFilter consisting of "
|
||||
r"<telegram.ext.filters.(Filters.)?_Forwarded object at .*?> or "
|
||||
r"<telegram.ext.filters.(Filters.)?entity object at .*?>>>")
|
||||
|
||||
def test_faulty_custom_filter(self):
|
||||
|
||||
class _CustomFilter(BaseFilter):
|
||||
pass
|
||||
|
||||
custom = _CustomFilter()
|
||||
|
||||
with self.assertRaises(NotImplementedError):
|
||||
(custom & Filters.text)(self.message)
|
||||
|
||||
|
||||
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 a object that represents Tests for Telegram ForceReply"""
|
||||
"""This module contains an object that represents Tests for Telegram ForceReply"""
|
||||
|
||||
import sys
|
||||
import unittest
|
||||
@@ -35,8 +35,10 @@ class ForceReplyTest(BaseTest, unittest.TestCase):
|
||||
self.force_reply = True
|
||||
self.selective = True
|
||||
|
||||
self.json_dict = {'force_reply': self.force_reply,
|
||||
'selective': self.selective,}
|
||||
self.json_dict = {
|
||||
'force_reply': self.force_reply,
|
||||
'selective': self.selective,
|
||||
}
|
||||
|
||||
def test_send_message_with_force_reply(self):
|
||||
message = self._bot.sendMessage(
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user