From b5680a1c1f821d510c9bdbe64c1a4104e8c9c02b Mon Sep 17 00:00:00 2001 From: eternnoir Date: Mon, 4 Jan 2016 22:24:18 +0800 Subject: [PATCH 01/12] Add InlineQuery class. --- telebot/types.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/telebot/types.py b/telebot/types.py index 71db219..08d23a7 100644 --- a/telebot/types.py +++ b/telebot/types.py @@ -515,3 +515,30 @@ class ReplyKeyboardMarkup(JsonSerializable): json_dict['selective'] = True return json.dumps(json_dict) + + +class InlineQuery(JsonDeserializable): + @classmethod + def de_json(cls, json_type): + obj = cls.check_json(json_type) + id = obj['id'] + from_user = obj['from'] + query = obj['query'] + offset = obj['offset'] + return cls(id, from_user, query, offset) + + def __init__(self, id, from_user, query, offset): + """ + This object represents an incoming inline query. + When the user sends an empty query, your bot could + return some default or trending results. + :param id: string Unique identifier for this query + :param from_user: User Sender + :param query: String Text of the query + :param offset: String Offset of the results to be returned, can be controlled by the bot + :return: InlineQuery Object + """ + self.id = id + self.from_user = from_user + self.query = query + self.offset = offset From 7eeda3bc4dfafbc2de2ed0995183aa5dced2fbb0 Mon Sep 17 00:00:00 2001 From: eternnoir Date: Mon, 4 Jan 2016 22:29:04 +0800 Subject: [PATCH 02/12] Update update object. --- telebot/types.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/telebot/types.py b/telebot/types.py index 08d23a7..b076c79 100644 --- a/telebot/types.py +++ b/telebot/types.py @@ -87,12 +87,21 @@ class Update(JsonDeserializable): def de_json(cls, json_type): obj = cls.check_json(json_type) update_id = obj['update_id'] - message = Message.de_json(obj['message']) - return cls(update_id, message) + message = None + inline_query = None + # TODO chosen_inline_result + chosen_inline_result = None + if 'message' in obj: + message = Message.de_json(obj['message']) + if 'inline_query' in obj: + inline_query = InlineQuery.de_json(obj['inline_query']) + return cls(update_id, message, inline_query, chosen_inline_result) - def __init__(self, update_id, message): + def __init__(self, update_id, message, inline_query, chosen_inline_result): self.update_id = update_id self.message = message + self.inline_query = inline_query + self.chosen_inline_result = chosen_inline_result class User(JsonDeserializable): From e9125466806e841c0b2ff3b91961b21e6f4b72ec Mon Sep 17 00:00:00 2001 From: eternnoir Date: Mon, 4 Jan 2016 22:53:08 +0800 Subject: [PATCH 03/12] Add ChosenInlineResult class. --- telebot/types.py | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/telebot/types.py b/telebot/types.py index b076c79..f24a91d 100644 --- a/telebot/types.py +++ b/telebot/types.py @@ -89,12 +89,13 @@ class Update(JsonDeserializable): update_id = obj['update_id'] message = None inline_query = None - # TODO chosen_inline_result chosen_inline_result = None if 'message' in obj: message = Message.de_json(obj['message']) if 'inline_query' in obj: inline_query = InlineQuery.de_json(obj['inline_query']) + if 'chosen_inline_result' in obj: + chosen_inline_result = ChosenInlineResult.de_json(obj['chosen_inline_result']) return cls(update_id, message, inline_query, chosen_inline_result) def __init__(self, update_id, message, inline_query, chosen_inline_result): @@ -531,7 +532,7 @@ class InlineQuery(JsonDeserializable): def de_json(cls, json_type): obj = cls.check_json(json_type) id = obj['id'] - from_user = obj['from'] + from_user = User.de_json(obj['from']) query = obj['query'] offset = obj['offset'] return cls(id, from_user, query, offset) @@ -551,3 +552,26 @@ class InlineQuery(JsonDeserializable): self.from_user = from_user self.query = query self.offset = offset + + +class ChosenInlineResult(JsonDeserializable): + @classmethod + def de_json(cls, json_type): + obj = cls.check_json(json_type) + result_id = obj['result_id'] + from_user = User.de_json(obj['from']) + query = obj['query'] + return cls(result_id, from_user, query) + + def __init__(self, result_id, from_user, query): + """ + This object represents a result of an inline query + that was chosen by the user and sent to their chat partner. + :param result_id: string The unique identifier for the result that was chosen. + :param from_user: User The user that chose the result. + :param query: String The query that was used to obtain the result. + :return: ChosenInlineResult Object. + """ + self.result_id = result_id + self.from_user = from_user + self.query = query From 79c46bccae23b8e360aefed8f9d62234f4c79f7e Mon Sep 17 00:00:00 2001 From: eternnoir Date: Mon, 4 Jan 2016 23:10:32 +0800 Subject: [PATCH 04/12] inline_hanlder done. --- telebot/__init__.py | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/telebot/__init__.py b/telebot/__init__.py index e831426..681ac07 100644 --- a/telebot/__init__.py +++ b/telebot/__init__.py @@ -66,6 +66,7 @@ class TeleBot: self.pre_message_subscribers_next_step = {} self.message_handlers = [] + self.inline_handlers = [] self.threaded = threaded if self.threaded: @@ -117,13 +118,20 @@ class TeleBot: self.skip_pending = False updates = self.get_updates(offset=(self.last_update_id + 1), timeout=timeout) new_messages = [] + new_inline_querys = [] for update in updates: if update.update_id > self.last_update_id: self.last_update_id = update.update_id - new_messages.append(update.message) - logger.debug('Received {0} new messages'.format(len(new_messages))) + if update.message: + new_messages.append(update.message) + if update.inline_query: + new_inline_querys.append(update.inline_query) + # TODO Chosen + logger.debug('Received {0} new updates'.format(len(updates))) if len(new_messages) > 0: self.process_new_messages(new_messages) + if len(new_inline_querys) > 0: + self.process_new_inline_query(new_inline_querys) def process_new_messages(self, new_messages): self._append_pre_next_step_handler() @@ -132,6 +140,9 @@ class TeleBot: self._notify_message_subscribers(new_messages) self._notify_message_next_handler(new_messages) + def process_new_inline_query(self, new_inline_querys): + self._notify_inline_handlers(new_inline_querys) + def __notify_update(self, new_messages): for listener in self.update_listener: self.__exec_task(listener, new_messages) @@ -504,6 +515,21 @@ class TeleBot: return decorator + def inline_handler(self, regexp=None, func=None): + + def decorator(fn): + handler_dict = {'function': fn} + filters = {} + if regexp: + filters['regexp'] = regexp + if func: + filters['lambda'] = func + handler_dict['filters'] = filters + self.inline_handlers.append(handler_dict) + return fn + + return decorator + @staticmethod def _test_message_handler(message_handler, message): for filter, filter_value in six.iteritems(message_handler['filters']): @@ -530,6 +556,13 @@ class TeleBot: self.__exec_task(message_handler['function'], message) break + def _notify_inline_handlers(self, inlien_querys): + for inline_query in inlien_querys: + for inline_handler in self.inline_handlers: + if self._test_message_handler(inline_handler, inline_query): + self.__exec_task(inline_handler['function'], inline_query) + break + class AsyncTeleBot(TeleBot): def __init__(self, *args, **kwargs): From a1267a76702ccf2424c200b45fef26b4ac9c207f Mon Sep 17 00:00:00 2001 From: eternnoir Date: Tue, 5 Jan 2016 09:57:25 +0800 Subject: [PATCH 05/12] Add InlineQueryResultArticle class. --- telebot/types.py | 56 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 19 deletions(-) diff --git a/telebot/types.py b/telebot/types.py index f24a91d..57d3020 100644 --- a/telebot/types.py +++ b/telebot/types.py @@ -1,24 +1,6 @@ # -*- coding: utf-8 -*- -""" -Available types -User -GroupChat -Message -PhotoSize -Audio -Document -Sticker -Video -Contact -Location -Update -InputFile -UserProfilePhotos -ReplyKeyboardMarkup -ReplyKeyboardHide -ForceReply -""" +# TODO InlineQueryResultArticle, InlineQueryResultPhoto, InlineQueryResultGif, InlineQueryResultMpeg4Gif, InlineQueryResultVideo import json import six @@ -575,3 +557,39 @@ class ChosenInlineResult(JsonDeserializable): self.result_id = result_id self.from_user = from_user self.query = query + + +class InlineQueryResultArticle(JsonSerializable): + def __init__(self, id, title, message_text, parse_mode=None, disable_web_page_preview=None, url=None, + hide_url=None, description=None, thumb_url=None, thumb_width=None, thumb_height=None): + self.type = 'article' + self.title = title + self.message_text = message_text + self.parse_mode = parse_mode + self.disable_web_page_preview = disable_web_page_preview + self.url = url + self.hide_url = hide_url + self.description = description + self.thumb_url = thumb_url + self.thumb_width = thumb_width + self.thumb_height = thumb_height + + def to_json(self): + json_dict = {'id': self.type, 'title': self.title, 'message_text': self.message_text} + if self.parse_mode: + json_dict['parse_mode'] = self.parse_mode + if self.disable_web_page_preview: + json_dict['disable_web_page_preview'] = self.disable_web_page_preview + if self.url: + json_dict['url'] = self.url + if self.hide_url: + json_dict['hide_url'] = self.hide_url + if self.description: + json_dict['description'] = self.description + if self.thumb_url: + json_dict['thumb_url'] = self.thumb_url + if self.thumb_width: + json_dict['thumb_width'] = self.thumb_width + if self.thumb_height: + json_dict['thumb_height'] = self.thumb_height + return json.dumps(json_dict) From fa6f16ca5e596401bb5fa106c62a72c60f4d6c77 Mon Sep 17 00:00:00 2001 From: eternnoir Date: Tue, 5 Jan 2016 10:24:21 +0800 Subject: [PATCH 06/12] Add InlineQueryResultPhoto class. --- telebot/types.py | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/telebot/types.py b/telebot/types.py index 57d3020..94e8025 100644 --- a/telebot/types.py +++ b/telebot/types.py @@ -593,3 +593,46 @@ class InlineQueryResultArticle(JsonSerializable): if self.thumb_height: json_dict['thumb_height'] = self.thumb_height return json.dumps(json_dict) + + +class InlineQueryResultPhoto(JsonSerializable): + def __init__(self, id, photo_url, mime_type=None, photo_width=None, photo_height=None, thumb_url=None, title=None, + description=None, caption=None, message_text=None, parse_mode=None, disable_web_page_preview=None): + self.type = 'photo' + self.id = id + self.photo_url = photo_url + self.mime_type = mime_type + self.photo_width = photo_width + self.photo_height = photo_height + self.thumb_url = thumb_url + self.title = title + self.description = description + self.caption = caption + self.message_text = message_text + self.parse_mode = parse_mode + self.disable_web_page_preview = disable_web_page_preview + + def to_json(self): + json_dict = {'id': self.type, 'photo_url': self.photo_url} + if self.mime_type: + json_dict['mime_type'] = self.mime_type + if self.photo_width: + json_dict['photo_width'] = self.photo_width + if self.photo_height: + json_dict['photo_height'] = self.photo_height + if self.thumb_url: + json_dict['thumb_url'] = self.thumb_url + if self.title: + json_dict['title'] = self.title + if self.description: + json_dict['description'] = self.description + if self.caption: + json_dict['caption'] = self.caption + if self.message_text: + json_dict['message_text'] = self.message_text + if self.parse_mode: + json_dict['parse_mode'] = self.parse_mode + if self.disable_web_page_preview: + json_dict['disable_web_page_preview'] = self.disable_web_page_preview + return json.dumps(json_dict) + From 0f0d76ca826521135a214038017fe1c0e2dc6e4a Mon Sep 17 00:00:00 2001 From: eternnoir Date: Tue, 5 Jan 2016 10:41:32 +0800 Subject: [PATCH 07/12] Add InlineQueryResultGif class. --- telebot/types.py | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/telebot/types.py b/telebot/types.py index 94e8025..d2068a5 100644 --- a/telebot/types.py +++ b/telebot/types.py @@ -563,6 +563,7 @@ class InlineQueryResultArticle(JsonSerializable): def __init__(self, id, title, message_text, parse_mode=None, disable_web_page_preview=None, url=None, hide_url=None, description=None, thumb_url=None, thumb_width=None, thumb_height=None): self.type = 'article' + self.id = id self.title = title self.message_text = message_text self.parse_mode = parse_mode @@ -575,7 +576,7 @@ class InlineQueryResultArticle(JsonSerializable): self.thumb_height = thumb_height def to_json(self): - json_dict = {'id': self.type, 'title': self.title, 'message_text': self.message_text} + json_dict = {'type': self.type, 'id': self.id, 'title': self.title, 'message_text': self.message_text} if self.parse_mode: json_dict['parse_mode'] = self.parse_mode if self.disable_web_page_preview: @@ -613,7 +614,7 @@ class InlineQueryResultPhoto(JsonSerializable): self.disable_web_page_preview = disable_web_page_preview def to_json(self): - json_dict = {'id': self.type, 'photo_url': self.photo_url} + json_dict = {'type': self.type, 'id': self.id, 'photo_url': self.photo_url} if self.mime_type: json_dict['mime_type'] = self.mime_type if self.photo_width: @@ -636,3 +637,38 @@ class InlineQueryResultPhoto(JsonSerializable): json_dict['disable_web_page_preview'] = self.disable_web_page_preview return json.dumps(json_dict) + +class InlineQueryResultGif(JsonSerializable): + def __init__(self, id, gif_url, gif_width=None, gif_height=None, thumb_url=None, title=None, caption=None, + message_text=None, parse_mode=None, disable_web_page_preview=None): + self.type = 'gif' + self.id = id + self.gif_url = gif_url + self.gif_width = gif_width + self.gif_height = gif_height + self.thumb_url = thumb_url + self.title = title + self.caption = caption + self.message_text = message_text + self.parse_mode = parse_mode + self.disable_web_page_preview = disable_web_page_preview + + def to_json(self): + json_dict = {'type': self.type, 'id': self.id, 'gif_url': self.gif_url} + if self.gif_height: + json_dict['gif_height'] = self.gif_height + if self.gif_width: + json_dict['gif_width'] = self.gif_width + if self.thumb_url: + json_dict['thumb_url'] = self.thumb_url + if self.title: + json_dict['title'] = self.title + if self.caption: + json_dict['caption'] = self.caption + if self.message_text: + json_dict['message_text'] = self.message_text + if self.parse_mode: + json_dict['parse_mode'] = self.parse_mode + if self.disable_web_page_preview: + json_dict['disable_web_page_preview'] = self.disable_web_page_preview + return json.dumps(json_dict) From 81a201f19fcf5f652c953c3e98c37fb3467abb00 Mon Sep 17 00:00:00 2001 From: eternnoir Date: Tue, 5 Jan 2016 10:51:33 +0800 Subject: [PATCH 08/12] Add InlineQueryResultMpeg4Gif class. --- telebot/types.py | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/telebot/types.py b/telebot/types.py index d2068a5..b034398 100644 --- a/telebot/types.py +++ b/telebot/types.py @@ -672,3 +672,39 @@ class InlineQueryResultGif(JsonSerializable): if self.disable_web_page_preview: json_dict['disable_web_page_preview'] = self.disable_web_page_preview return json.dumps(json_dict) + + +class InlineQueryResultMpeg4Gif(JsonSerializable): + def __init__(self, id, mpeg4_url, mpeg4_width=None, mpeg4_height=None, thumb_url=None, title=None, caption=None, + message_text=None, parse_mode=None, disable_web_page_preview=None): + self.type = 'mpeg4_gif' + self.id = id + self.mpeg4_url = mpeg4_url + self.mpeg4_width = mpeg4_width + self.mpeg4_height = mpeg4_height + self.thumb_url = thumb_url + self.title = title + self.caption = caption + self.message_text = message_text + self.parse_mode = parse_mode + self.disable_web_page_preview = disable_web_page_preview + + def to_json(self): + json_dict = {'type': self.type, 'id': self.id, 'mpeg4_url': self.mpeg4_url} + if self.mpeg4_width: + json_dict['mpeg4_width'] = self.mpeg4_width + if self.mpeg4_height: + json_dict['mpeg4_height'] = self.mpeg4_height + if self.thumb_url: + json_dict['thumb_url'] = self.thumb_url + if self.title: + json_dict['title'] = self.title + if self.caption: + json_dict['caption'] = self.caption + if self.message_text: + json_dict['message_text'] = self.message_text + if self.parse_mode: + json_dict['parse_mode'] = self.parse_mode + if self.disable_web_page_preview: + json_dict['disable_web_page_preview'] = self.disable_web_page_preview + return json.dumps(json_dict) From c214f8000e0e3ab9c36423a178f6d9627f39d3b7 Mon Sep 17 00:00:00 2001 From: eternnoir Date: Tue, 5 Jan 2016 11:03:05 +0800 Subject: [PATCH 09/12] Add InlineQueryResultVideo class. --- telebot/types.py | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/telebot/types.py b/telebot/types.py index b034398..5af3a39 100644 --- a/telebot/types.py +++ b/telebot/types.py @@ -708,3 +708,44 @@ class InlineQueryResultMpeg4Gif(JsonSerializable): if self.disable_web_page_preview: json_dict['disable_web_page_preview'] = self.disable_web_page_preview return json.dumps(json_dict) + + +class InlineQueryResultVideo(JsonSerializable): + def __init__(self, id, video_url, mime_type, message_text=None, parse_mode=None, disable_web_page_preview=None, + video_width=None, video_height=None, video_duration=None, thumb_url=None, title=None, + description=None): + self.type = 'video' + self.id = id + self.video_url = video_url + self.mime_type = mime_type + self.message_text = message_text + self.parse_mode = parse_mode + self.disable_web_page_preview = disable_web_page_preview + self.video_width = video_width + self.video_height = video_height + self.video_duration = video_duration + self.thumb_url = thumb_url + self.title = title + self.description = description + + def to_json(self): + json_dict = {'type': self.type, 'id': self.id, 'video_url': self.video_url, 'mime_type': self.mime_type} + if self.message_text: + json_dict['message_text'] = self.message_text + if self.parse_mode: + json_dict['parse_mode'] = self.parse_mode + if self.disable_web_page_preview: + json_dict['disable_web_page_preview'] = self.disable_web_page_preview + if self.video_width: + json_dict['video_width'] = self.video_width + if self.video_height: + json_dict['video_height'] = self.video_height + if self.video_duration: + json_dict['video_duration'] = self.video_duration + if self.thumb_url: + json_dict['thumb_url'] = self.thumb_url + if self.title: + json_dict['title'] = self.title + if self.description: + json_dict['description'] = self.description + return json.dumps(json_dict) From c706a7aba3cd30d6c2fd2b715b6a1ccc9cd010ec Mon Sep 17 00:00:00 2001 From: eternnoir Date: Tue, 5 Jan 2016 13:18:32 +0800 Subject: [PATCH 10/12] Handler done. --- telebot/__init__.py | 74 ++++++++++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 34 deletions(-) diff --git a/telebot/__init__.py b/telebot/__init__.py index 681ac07..5d28391 100644 --- a/telebot/__init__.py +++ b/telebot/__init__.py @@ -11,7 +11,7 @@ import logging logger = logging.getLogger('TeleBot') formatter = logging.Formatter( - '%(asctime)s (%(filename)s:%(lineno)d %(threadName)s) %(levelname)s - %(name)s: "%(message)s"' + '%(asctime)s (%(filename)s:%(lineno)d %(threadName)s) %(levelname)s - %(name)s: "%(message)s"' ) console_output_handler = logging.StreamHandler(sys.stderr) @@ -67,6 +67,7 @@ class TeleBot: self.message_handlers = [] self.inline_handlers = [] + self.chosen_inline_handlers = [] self.threaded = threaded if self.threaded: @@ -104,7 +105,7 @@ class TeleBot: for update in updates: if update.update_id > self.last_update_id: self.last_update_id = update.update_id - updates = self.get_updates(offset=self.last_update_id+1, timeout=1) + updates = self.get_updates(offset=self.last_update_id + 1, timeout=1) return total def __retrieve_updates(self, timeout=20): @@ -119,6 +120,7 @@ class TeleBot: updates = self.get_updates(offset=(self.last_update_id + 1), timeout=timeout) new_messages = [] new_inline_querys = [] + new_chosen_inline_results = [] for update in updates: if update.update_id > self.last_update_id: self.last_update_id = update.update_id @@ -126,22 +128,28 @@ class TeleBot: new_messages.append(update.message) if update.inline_query: new_inline_querys.append(update.inline_query) - # TODO Chosen + if update.chosen_inline_result: + new_chosen_inline_results.append(update.chosen_inline_result) logger.debug('Received {0} new updates'.format(len(updates))) if len(new_messages) > 0: self.process_new_messages(new_messages) if len(new_inline_querys) > 0: self.process_new_inline_query(new_inline_querys) + if len(new_chosen_inline_results) > 0: + self.process_new_chosen_inline_query(new_chosen_inline_results) def process_new_messages(self, new_messages): self._append_pre_next_step_handler() self.__notify_update(new_messages) - self._notify_command_handlers(new_messages) + self._notify_command_handlers(self.message_handlers, new_messages) self._notify_message_subscribers(new_messages) self._notify_message_next_handler(new_messages) def process_new_inline_query(self, new_inline_querys): - self._notify_inline_handlers(new_inline_querys) + self._notify_command_handlers(self.inline_handlers, new_inline_querys) + + def process_new_chosen_inline_query(self, new_chosen_inline_querys): + self._notify_command_handlers(self.chosen_inline_handlers, new_chosen_inline_querys) def __notify_update(self, new_messages): for listener in self.update_listener: @@ -171,9 +179,9 @@ class TeleBot: polling_thread = util.WorkerThread(name="PollingThread") or_event = util.OrEvent( - polling_thread.done_event, - polling_thread.exception_event, - self.worker_pool.exception_event + polling_thread.done_event, + polling_thread.exception_event, + self.worker_pool.exception_event ) while not self.__stop_polling.wait(interval): @@ -282,8 +290,8 @@ class TeleBot: :return: API reply. """ return types.Message.de_json( - apihelper.send_message(self.token, chat_id, text, disable_web_page_preview, reply_to_message_id, - reply_markup, parse_mode)) + apihelper.send_message(self.token, chat_id, text, disable_web_page_preview, reply_to_message_id, + reply_markup, parse_mode)) def forward_message(self, chat_id, from_chat_id, message_id): """ @@ -306,7 +314,7 @@ class TeleBot: :return: API reply. """ return types.Message.de_json( - apihelper.send_photo(self.token, chat_id, photo, caption, reply_to_message_id, reply_markup)) + apihelper.send_photo(self.token, chat_id, photo, caption, reply_to_message_id, reply_markup)) def send_audio(self, chat_id, audio, duration=None, performer=None, title=None, reply_to_message_id=None, reply_markup=None): @@ -322,8 +330,8 @@ class TeleBot: :return: Message """ return types.Message.de_json( - apihelper.send_audio(self.token, chat_id, audio, duration, performer, title, reply_to_message_id, - reply_markup)) + apihelper.send_audio(self.token, chat_id, audio, duration, performer, title, reply_to_message_id, + reply_markup)) def send_voice(self, chat_id, voice, duration=None, reply_to_message_id=None, reply_markup=None): """ @@ -336,7 +344,7 @@ class TeleBot: :return: Message """ return types.Message.de_json( - apihelper.send_voice(self.token, chat_id, voice, duration, reply_to_message_id, reply_markup)) + apihelper.send_voice(self.token, chat_id, voice, duration, reply_to_message_id, reply_markup)) def send_document(self, chat_id, data, reply_to_message_id=None, reply_markup=None): """ @@ -348,7 +356,7 @@ class TeleBot: :return: API reply. """ return types.Message.de_json( - apihelper.send_data(self.token, chat_id, data, 'document', reply_to_message_id, reply_markup)) + apihelper.send_data(self.token, chat_id, data, 'document', reply_to_message_id, reply_markup)) def send_sticker(self, chat_id, data, reply_to_message_id=None, reply_markup=None): """ @@ -360,7 +368,7 @@ class TeleBot: :return: API reply. """ return types.Message.de_json( - apihelper.send_data(self.token, chat_id, data, 'sticker', reply_to_message_id, reply_markup)) + apihelper.send_data(self.token, chat_id, data, 'sticker', reply_to_message_id, reply_markup)) def send_video(self, chat_id, data, duration=None, caption=None, reply_to_message_id=None, reply_markup=None): """ @@ -374,7 +382,7 @@ class TeleBot: :return: """ return types.Message.de_json( - apihelper.send_video(self.token, chat_id, data, duration, caption, reply_to_message_id, reply_markup)) + apihelper.send_video(self.token, chat_id, data, duration, caption, reply_to_message_id, reply_markup)) def send_location(self, chat_id, latitude, longitude, reply_to_message_id=None, reply_markup=None): """ @@ -387,7 +395,7 @@ class TeleBot: :return: API reply. """ return types.Message.de_json( - apihelper.send_location(self.token, chat_id, latitude, longitude, reply_to_message_id, reply_markup)) + apihelper.send_location(self.token, chat_id, latitude, longitude, reply_to_message_id, reply_markup)) def send_chat_action(self, chat_id, action): """ @@ -515,21 +523,26 @@ class TeleBot: return decorator - def inline_handler(self, regexp=None, func=None): - + def inline_handler(self, func): def decorator(fn): handler_dict = {'function': fn} - filters = {} - if regexp: - filters['regexp'] = regexp - if func: - filters['lambda'] = func + filters = {'lambda': func} handler_dict['filters'] = filters self.inline_handlers.append(handler_dict) return fn return decorator + def chosen_inline_handler(self, func): + def decorator(fn): + handler_dict = {'function': fn} + filters = {'lambda': func} + handler_dict['filters'] = filters + self.chosen_inline_handlers.append(handler_dict) + return fn + + return decorator + @staticmethod def _test_message_handler(message_handler, message): for filter, filter_value in six.iteritems(message_handler['filters']): @@ -549,20 +562,13 @@ class TeleBot: return filter_value(message) return False - def _notify_command_handlers(self, new_messages): + def _notify_command_handlers(self, handlers, new_messages): for message in new_messages: - for message_handler in self.message_handlers: + for message_handler in handlers: if self._test_message_handler(message_handler, message): self.__exec_task(message_handler['function'], message) break - def _notify_inline_handlers(self, inlien_querys): - for inline_query in inlien_querys: - for inline_handler in self.inline_handlers: - if self._test_message_handler(inline_handler, inline_query): - self.__exec_task(inline_handler['function'], inline_query) - break - class AsyncTeleBot(TeleBot): def __init__(self, *args, **kwargs): From 94f1bbd40235e689190b6f8db553d1c3b420879e Mon Sep 17 00:00:00 2001 From: eternnoir Date: Tue, 5 Jan 2016 14:07:47 +0800 Subject: [PATCH 11/12] Almost done. --- telebot/__init__.py | 3 +++ telebot/apihelper.py | 31 +++++++++++++++++++++++++++---- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/telebot/__init__.py b/telebot/__init__.py index 5d28391..07590f3 100644 --- a/telebot/__init__.py +++ b/telebot/__init__.py @@ -415,6 +415,9 @@ class TeleBot: """ return self.send_message(message.chat.id, text, reply_to_message_id=message.message_id, **kwargs) + def answer_inline_query(self, inline_query_id, results, cache_time=None, is_personal=None, next_offset=None): + return apihelper.answer_inline_query(self.token, inline_query_id, results, cache_time, is_personal, next_offset) + def register_for_reply(self, message, callback): """ Registers a callback function to be notified when a reply to `message` arrives. diff --git a/telebot/apihelper.py b/telebot/apihelper.py index 411e9c5..7ae8556 100644 --- a/telebot/apihelper.py +++ b/telebot/apihelper.py @@ -42,19 +42,19 @@ def _check_result(method_name, result): :return: The result parsed to a JSON dictionary. """ if result.status_code != 200: - msg = 'The server returned HTTP {0} {1}. Response body:\n[{2}]'\ + msg = 'The server returned HTTP {0} {1}. Response body:\n[{2}]' \ .format(result.status_code, result.reason, result.text.encode('utf8')) raise ApiException(msg, method_name, result) try: result_json = result.json() except: - msg = 'The server returned an invalid JSON response. Response body:\n[{0}]'\ + msg = 'The server returned an invalid JSON response. Response body:\n[{0}]' \ .format(result.text.encode('utf8')) raise ApiException(msg, method_name, result) if not result_json['ok']: - msg = 'Error code: {0} Description: {1}'\ + msg = 'Error code: {0} Description: {1}' \ .format(result_json['error_code'], result_json['description']) raise ApiException(msg, method_name, result) return result_json @@ -74,7 +74,7 @@ def download_file(token, file_path): url = FILE_URL.format(token, file_path) result = requests.get(url) if result.status_code != 200: - msg = 'The server returned HTTP {0} {1}. Response body:\n[{2}]'\ + msg = 'The server returned HTTP {0} {1}. Response body:\n[{2}]' \ .format(result.status_code, result.reason, result.text) raise ApiException(msg, 'Download file', result) return result.content @@ -258,11 +258,34 @@ def get_method_by_type(data_type): return r'sendSticker' +def answer_inline_query(token, inline_query_id, results, cache_time=None, is_personal=None, next_offset=None): + method_url = 'answerInlineQuery' + payload = {'inline_query_id': inline_query_id, 'results': _convert_inline_results(results)} + if cache_time: + payload['cache_time'] = cache_time + if is_personal: + payload['is_personal'] = is_personal + if next_offset: + payload['next_offset'] = next_offset + return _make_request(token, method_url, params=payload) + + +def _convert_inline_results(results): + ret = '' + for r in results: + if isinstance(r, types.JsonSerializable): + ret = ret + r.to_json() + ',' + if len(ret) > 0: + ret = ret[:-1] + return '[' + ret + ']' + + def _convert_markup(markup): if isinstance(markup, types.JsonSerializable): return markup.to_json() return markup + class ApiException(Exception): """ This class represents an Exception thrown when a call to the Telegram API fails. From 8278eef7f38740adafe5eee925b8a95ab61c468a Mon Sep 17 00:00:00 2001 From: eternnoir Date: Tue, 5 Jan 2016 14:58:19 +0800 Subject: [PATCH 12/12] Add inline bot example. --- examples/inline_example.py | 41 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 examples/inline_example.py diff --git a/examples/inline_example.py b/examples/inline_example.py new file mode 100644 index 0000000..4273178 --- /dev/null +++ b/examples/inline_example.py @@ -0,0 +1,41 @@ +# This example show how to write an inline mode telegramt bot use pyTelegramBotAPI. +import telebot +import time +import sys +from telebot import types + +API_TOKEN = '' + +bot = telebot.TeleBot(API_TOKEN) + + +@bot.inline_handler(lambda query: query.query == 'text') +def query(inline_query): + try: + r = types.InlineQueryResultArticle('1', 'Result', inline_query.query) + bot.answer_inline_query(inline_query.id, [r]) + except Exception as e: + print(e) + + +@bot.inline_handler(lambda query: len(query.query) is 0) +def default_query(inline_query): + try: + r = types.InlineQueryResultArticle('1', 'default', 'default') + bot.answer_inline_query(inline_query.id, [r]) + except Exception as e: + print(e) + + +def main_loop(): + bot.polling(True) + while 1: + time.sleep(3) + + +if __name__ == '__main__': + try: + main_loop() + except KeyboardInterrupt: + print >> sys.stderr, '\nExiting by user request.\n' + sys.exit(0)