From 073d7949dcccdaa18e9ad03e84792f3dd8d36d2d Mon Sep 17 00:00:00 2001 From: Juan Madurga Date: Mon, 30 May 2016 15:59:45 +0200 Subject: [PATCH 01/10] fix callbackquery to_dict --- telegram/callbackquery.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/telegram/callbackquery.py b/telegram/callbackquery.py index 440ddce8c..97ab956e2 100644 --- a/telegram/callbackquery.py +++ b/telegram/callbackquery.py @@ -43,3 +43,14 @@ class CallbackQuery(TelegramObject): data['message'] = Message.de_json(data.get('message')) return CallbackQuery(**data) + + def to_dict(self): + """ + Returns: + dict: + """ + data = super(CallbackQuery, self).to_dict() + + # Required + data['from'] = data.pop('from_user', None) + return data From 98be6abc11a9713f705a80694be5c261dfae5029 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jannes=20H=C3=B6ke?= Date: Tue, 31 May 2016 21:07:47 +0200 Subject: [PATCH 02/10] Remove clibot.py example --- examples/clibot.py | 164 --------------------------------------------- 1 file changed, 164 deletions(-) delete mode 100644 examples/clibot.py diff --git a/examples/clibot.py b/examples/clibot.py deleted file mode 100644 index 1ace32377..000000000 --- a/examples/clibot.py +++ /dev/null @@ -1,164 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# -# Example Bot to show some of the functionality of the library -# 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 handler functions are defined. Then, those functions are passed to -the Dispatcher and registered at their respective places. -Then, the bot is started and the CLI-Loop is entered, where all text inputs are -inserted into the update queue for the bot to handle. - -Usage: -Repeats messages with a delay. -Reply to last chat from the command line by typing "/reply " -Type 'stop' on the command line to stop the bot. -""" - -from telegram.ext import Updater, StringCommandHandler, StringRegexHandler, \ - MessageHandler, CommandHandler, RegexHandler, Filters -from telegram.ext.dispatcher import run_async -from time import sleep -import logging - -from future.builtins import input - -# Enable Logging -logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', - level=logging.INFO) - -logger = logging.getLogger(__name__) - -# We use this var to save the last chat id, so we can reply to it -last_chat_id = 0 - - -# Define a few (command) handler callback functions. These usually take the -# two arguments bot and update. Error handlers also receive the raised -# TelegramError object in error. -def start(bot, update): - """ Answer in Telegram """ - bot.sendMessage(update.message.chat_id, text='Hi!') - - -def help(bot, update): - """ Answer in Telegram """ - bot.sendMessage(update.message.chat_id, text='Help!') - - -def any_message(bot, update): - """ Print to console """ - - # Save last chat_id to use in reply handler - global last_chat_id - last_chat_id = update.message.chat_id - - logger.info("New message\nFrom: %s\nchat_id: %d\nText: %s" % - (update.message.from_user, update.message.chat_id, update.message.text)) - - -@run_async -def message(bot, update): - """ - Example for an asynchronous handler. It's not guaranteed that replies will - be in order when using @run_async. Also, you have to include **kwargs in - your parameter list. The kwargs contain all optional parameters that are - """ - - sleep(2) # IO-heavy operation here - bot.sendMessage(update.message.chat_id, text='Echo: %s' % update.message.text) - - -# These handlers are for updates of type str. We use them to react to inputs -# on the command line interface -def cli_reply(bot, update, args): - """ - For any update of type telegram.Update or str that contains a command, you - can get the argument list by appending args to the function parameters. - Here, we reply to the last active chat with the text after the command. - """ - if last_chat_id is not 0: - bot.sendMessage(chat_id=last_chat_id, text=' '.join(args)) - - -def cli_noncommand(bot, update, update_queue): - """ - You can also get the update queue as an argument in any handler by - appending it to the argument list. Be careful with this though. - Here, we put the input string back into the queue, but as a command. - - To learn more about those optional handler parameters, read the - documentation of the Handler classes. - """ - update_queue.put('/%s' % update) - - -def error(bot, update, error): - """ Print error to console """ - logger.warn('Update %s caused error %s' % (update, error)) - - -def main(): - # Create the EventHandler and pass it your bot's token. - token = 'TOKEN' - updater = Updater(token, workers=10) - - # Get the dispatcher to register handlers - dp = updater.dispatcher - - # This is how we add handlers for Telegram messages - dp.add_handler(CommandHandler("start", start)) - dp.add_handler(CommandHandler("help", help)) - # Message handlers only receive updates that don't contain commands - dp.add_handler(MessageHandler([Filters.text], message)) - # Regex handlers will receive all updates on which their regex matches, - # but we have to add it in a separate group, since in one group, - # only one handler will be executed - dp.add_handler(RegexHandler('.*', any_message), group=1) - - # String handlers work pretty much the same. Note that we have to tell - # the handler to pass the args or update_queue parameter - dp.add_handler(StringCommandHandler('reply', cli_reply, pass_args=True)) - dp.add_handler(StringRegexHandler('[^/].*', cli_noncommand, pass_update_queue=True)) - - # All TelegramErrors are caught for you and delivered to the error - # handler(s). Other types of Errors are not caught. - dp.add_error_handler(error) - - # Start the Bot and store the update Queue, so we can insert updates - update_queue = updater.start_polling(timeout=10) - ''' - # Alternatively, run with webhook: - - update_queue = updater.start_webhook('0.0.0.0', - 443, - url_path=token, - cert='cert.pem', - key='key.key', - webhook_url='https://example.com/%s' - % token) - - # Or, if SSL is handled by a reverse proxy, the webhook URL is already set - # and the reverse proxy is configured to deliver directly to port 6000: - - update_queue = updater.start_webhook('0.0.0.0', 6000) - ''' - - # Start CLI-Loop - while True: - text = input() - - # Gracefully stop the event handler - if text == 'stop': - updater.stop() - break - - # else, put the text into the update queue to be handled by our handlers - elif len(text) > 0: - update_queue.put(text) - - -if __name__ == '__main__': - main() From da95341d5b05fd0b81af50aba44c114e86f97a68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jannes=20H=C3=B6ke?= Date: Wed, 1 Jun 2016 00:05:09 +0200 Subject: [PATCH 03/10] Update README.rst --- README.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.rst b/README.rst index fb82b1645..b6073897f 100644 --- a/README.rst +++ b/README.rst @@ -129,8 +129,6 @@ code and building on top of it. - `timerbot `_ uses the ``JobQueue`` to send timed messages. -- `clibot `_ has a command line interface. - Examples using only the pure API: - `echobot `_ replies back messages. From bbbc6225173e2ed836d9a3d95771f2d89bd13b78 Mon Sep 17 00:00:00 2001 From: leandrotoledo Date: Fri, 3 Jun 2016 13:28:29 -0400 Subject: [PATCH 04/10] Adds @message decorator to editMessageText #320 --- telegram/bot.py | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/telegram/bot.py b/telegram/bot.py index b4e1de773..2145bee79 100644 --- a/telegram/bot.py +++ b/telegram/bot.py @@ -1009,6 +1009,7 @@ class Bot(TelegramObject): return result @log + @message def editMessageText(self, text, chat_id=None, @@ -1016,7 +1017,6 @@ class Bot(TelegramObject): inline_message_id=None, parse_mode=None, disable_web_page_preview=None, - reply_markup=None, **kwargs): """Use this method to edit text messages sent by the bot or via the bot (for inline bots). @@ -1043,6 +1043,10 @@ class Bot(TelegramObject): A JSON-serialized object for an inline keyboard. Keyword Args: + reply_markup (Optional[:class:`telegram.ReplyMarkup`]): Additional + interface options. A JSON-serialized object for an inline + keyboard, custom reply keyboard, instructions to hide reply + keyboard or to force a reply from the user. timeout (Optional[float]): If this value is specified, use it as the definitive timeout (in seconds) for urlopen() operations. @@ -1070,15 +1074,8 @@ class Bot(TelegramObject): data['parse_mode'] = parse_mode if disable_web_page_preview: data['disable_web_page_preview'] = disable_web_page_preview - if reply_markup: - if isinstance(reply_markup, ReplyMarkup): - data['reply_markup'] = reply_markup.to_json() - else: - data['reply_markup'] = reply_markup - result = request.post(url, data, timeout=kwargs.get('timeout')) - - return Message.de_json(result) + return url, data @log @message From f0b91ecf467aef757d9f3073bf40cc5fa8f3ac59 Mon Sep 17 00:00:00 2001 From: leandrotoledo Date: Fri, 3 Jun 2016 13:44:24 -0400 Subject: [PATCH 05/10] Fix travis --- tests/test_photo.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/test_photo.py b/tests/test_photo.py index 994d0bd3e..15db261e4 100644 --- a/tests/test_photo.py +++ b/tests/test_photo.py @@ -35,15 +35,14 @@ class PhotoTest(BaseTest, unittest.TestCase): def setUp(self): self.photo_file = open('tests/data/telegram.jpg', 'rb') - self.photo_file_id = 'AgADAQADvb8xGx8j9QcpZDKxYoFK3bfX1i8ABFX_dgMWoKDuQugAAgI' + self.photo_file_id = 'AgADAQADgEsyGx8j9QfmDMmwkPBrFcKRzy8ABHW8ul9nW7FoNHYBAAEC' self.photo_file_url = 'https://raw.githubusercontent.com/python-telegram-bot/python-telegram-bot/master/tests/data/telegram.jpg' self.width = 300 self.height = 300 self.thumb = { 'width': 90, 'height': 90, - 'file_id': - 'AgADAQADvb8xGx8j9QcpZDKxYoFK3bfX1i8ABBxRLXFhLnhIQ-gAAgI', + 'file_id': 'AgADAQADgEsyGx8j9QfmDMmwkPBrFcKRzy8ABD64nkFkjujeNXYBAAEC', 'file_size': 1478 } self.file_size = 10209 From 897f9615f0e49352f71ff0522bcb4c3710424e52 Mon Sep 17 00:00:00 2001 From: leandrotoledo Date: Fri, 10 Jun 2016 09:44:17 -0400 Subject: [PATCH 06/10] Bump version to v4.2.1 --- CHANGES.rst | 7 +++++++ telegram/__init__.py | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 511b179f3..d142ead5c 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,3 +1,10 @@ +**2016-06-10** + +*Released 4.2.1* + +- Fix ``CallbackQuery.to_dict()`` bug (thanks to @jlmadurga) +- Fix ``editMessageText`` exception when receiving a ``CallbackQuery`` + **2016-05-28** *Released 4.2* diff --git a/telegram/__init__.py b/telegram/__init__.py index 6437cdad0..1bf9dd131 100644 --- a/telegram/__init__.py +++ b/telegram/__init__.py @@ -82,7 +82,7 @@ from .update import Update from .bot import Bot __author__ = 'devs@python-telegram-bot.org' -__version__ = '4.2.0' +__version__ = '4.2.1' __all__ = ['Audio', 'Bot', 'Chat', 'ChatMember', 'ChatAction', 'ChosenInlineResult', 'CallbackQuery', 'Contact', 'Document', 'Emoji', 'File', 'ForceReply', 'InlineKeyboardButton', 'InlineKeyboardMarkup', 'InlineQuery', 'InlineQueryResult', From 94fd6851ab35b40e31896a00674329c8bdfb1f9f Mon Sep 17 00:00:00 2001 From: Rahiel Kasim Date: Sun, 12 Jun 2016 15:30:56 +0200 Subject: [PATCH 07/10] more robust echobot, let roboed go --- examples/{legacy => }/echobot.py | 17 ++++++++------ examples/legacy/roboed.py | 38 -------------------------------- 2 files changed, 10 insertions(+), 45 deletions(-) rename examples/{legacy => }/echobot.py (78%) delete mode 100644 examples/legacy/roboed.py diff --git a/examples/legacy/echobot.py b/examples/echobot.py similarity index 78% rename from examples/legacy/echobot.py rename to examples/echobot.py index c914c9dc0..caf44d774 100644 --- a/examples/legacy/echobot.py +++ b/examples/echobot.py @@ -1,16 +1,19 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- # -# Simple Bot to reply to Telegram messages +# Simple Bot to reply to Telegram messages. This is built on the API wrapper, see +# echobot2.py to see the same example built on the telegram.ext bot framework. # This program is dedicated to the public domain under the CC0 license. - import logging import telegram from telegram.error import NetworkError, Unauthorized from time import sleep +update_id = None + def main(): + global update_id # Telegram Bot Authorization Token bot = telegram.Bot('TOKEN') @@ -25,7 +28,7 @@ def main(): while True: try: - update_id = echo(bot, update_id) + echo(bot) except NetworkError: sleep(1) except Unauthorized: @@ -33,21 +36,21 @@ def main(): update_id += 1 -def echo(bot, update_id): - +def echo(bot): + global update_id # Request updates after the last update_id for update in bot.getUpdates(offset=update_id, timeout=10): # chat_id is required to reply to any message chat_id = update.message.chat_id update_id = update.update_id + 1 + if not update.message: # we ignore updates without messages + continue message = update.message.text if message: # Reply to the message bot.sendMessage(chat_id=chat_id, text=message) - return update_id - if __name__ == '__main__': main() diff --git a/examples/legacy/roboed.py b/examples/legacy/roboed.py deleted file mode 100644 index 1a04668b0..000000000 --- a/examples/legacy/roboed.py +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# -# Robô Ed Telegram Bot -# This program is dedicated to the public domain under the CC0 license. - -import logging -import telegram -import urllib - - -def main(): - logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s') - bot = telegram.Bot('TOKEN') # Telegram Bot Authorization Token - - LAST_UPDATE_ID = bot.getUpdates()[-1].update_id # Get lastest update - - while True: - for update in bot.getUpdates(offset=LAST_UPDATE_ID, timeout=10): - text = update.message.text - chat_id = update.message.chat.id - update_id = update.update_id - - if text: - roboed = ed(text) # Ask something to Robô Ed - bot.sendMessage(chat_id=chat_id, text=roboed) - LAST_UPDATE_ID = update_id + 1 - - -def ed(text): - url = 'http://www.ed.conpet.gov.br/mod_perl/bot_gateway.cgi?server=0.0.0.0%3A8085&charset_post=utf-8&charset=utf-8&pure=1&js=0&tst=1&msg=' + text - data = urllib.urlopen(url).read() - - return data.strip() - - -if __name__ == '__main__': - main() From deb9de0ba0a7aafc4a7da11558e9dfc3e7ecf2dc Mon Sep 17 00:00:00 2001 From: Rahiel Kasim Date: Sun, 12 Jun 2016 16:58:18 +0200 Subject: [PATCH 08/10] README: remove roboed, rename example --- README.rst | 6 +----- examples/{inlinekeyboard_example.py => inlinekeyboard.py} | 0 2 files changed, 1 insertion(+), 5 deletions(-) rename examples/{inlinekeyboard_example.py => inlinekeyboard.py} (100%) diff --git a/README.rst b/README.rst index b6073897f..6442984db 100644 --- a/README.rst +++ b/README.rst @@ -129,11 +129,7 @@ code and building on top of it. - `timerbot `_ uses the ``JobQueue`` to send timed messages. -Examples using only the pure API: - -- `echobot `_ replies back messages. - -- `roboed `_ talks to `Robô Ed `_. +- `echobot `_ uses only the pure API to echo messages. Look at the examples on the `wiki `_ to see other bots the community has built. diff --git a/examples/inlinekeyboard_example.py b/examples/inlinekeyboard.py similarity index 100% rename from examples/inlinekeyboard_example.py rename to examples/inlinekeyboard.py From e10fa66286b986887db47ddbeafff893357dfa44 Mon Sep 17 00:00:00 2001 From: Rahiel Kasim Date: Sun, 12 Jun 2016 17:06:03 +0200 Subject: [PATCH 09/10] echobot: simplify handling messageless updates --- examples/echobot.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/examples/echobot.py b/examples/echobot.py index caf44d774..06ae496e6 100644 --- a/examples/echobot.py +++ b/examples/echobot.py @@ -43,13 +43,10 @@ def echo(bot): # chat_id is required to reply to any message chat_id = update.message.chat_id update_id = update.update_id + 1 - if not update.message: # we ignore updates without messages - continue - message = update.message.text - if message: + if update.message: # your bot can receive updates without messages # Reply to the message - bot.sendMessage(chat_id=chat_id, text=message) + bot.sendMessage(chat_id=chat_id, text=update.message.text) if __name__ == '__main__': From 4f101a79bb20235df22ac85dc145e2a8d015fd54 Mon Sep 17 00:00:00 2001 From: leandrotoledo Date: Sun, 19 Jun 2016 17:08:12 -0400 Subject: [PATCH 10/10] Update travis yapf [ci skip] --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 781455b0e..f675a1683 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,7 +4,7 @@ - id: yapf files: ^(telegram|tests)/.*\.py$ - repo: git://github.com/pre-commit/pre-commit-hooks - sha: adbb569fe9a64ad9bce3b53a77f1bc39ef31f682 + sha: 6dfcb89af3c9b4d172cc2e5a8a2fa0f54615a338 hooks: - id: flake8 files: ^telegram/.*\.py$