mirror of
https://github.com/eternnoir/pyTelegramBotAPI.git
synced 2023-08-10 21:12:57 +03:00
Compare commits
33 Commits
Author | SHA1 | Date | |
---|---|---|---|
00d6481818 | |||
a74ed6e3ab | |||
38eb2ba833 | |||
93dc1cd92e | |||
a7469e6b14 | |||
b8f251140d | |||
e2e6b07fdb | |||
a2ceffecc8 | |||
805e3554de | |||
94d34747d1 | |||
8278eef7f3 | |||
94f1bbd402 | |||
c706a7aba3 | |||
c214f8000e | |||
81a201f19f | |||
0f0d76ca82 | |||
fa6f16ca5e | |||
a1267a7670 | |||
79c46bccae | |||
e912546680 | |||
7eeda3bc4d | |||
b5680a1c1f | |||
7514c617fc | |||
32f3a64720 | |||
3a08111f10 | |||
eeff4e7bf8 | |||
c37b3625aa | |||
a3519ff539 | |||
43ad415320 | |||
fb7c79fdfb | |||
413f081b19 | |||
cea0604ede | |||
be639ef4dd |
37
README.md
37
README.md
@ -17,6 +17,7 @@
|
||||
* [Message handlers](#message-handlers)
|
||||
* [TeleBot](#telebot)
|
||||
* [Reply markup](#reply-markup)
|
||||
* [Inline Mode](#inline-mode)
|
||||
* [Advanced use of the API](#advanced-use-of-the-api)
|
||||
* [Asynchronous delivery of messages](#asynchronous-delivery-of-messages)
|
||||
* [Sending large text messages](#sending-large-text-messages)
|
||||
@ -120,8 +121,8 @@ To start the bot, simply open up a terminal and enter `python echo_bot.py` to ru
|
||||
|
||||
All types are defined in types.py. They are all completely in line with the [Telegram API's definition of the types](https://core.telegram.org/bots/api#available-types), except for the Message's `from` field, which is renamed to `from_user` (because `from` is a Python reserved token). Thus, attributes such as `message_id` can be accessed directly with `message.message_id`. Note that `message.chat` can be either an instance of `User` or `GroupChat` (see [How can I distinguish a User and a GroupChat in message.chat?](#how-can-i-distinguish-a-user-and-a-groupchat-in-messagechat)).
|
||||
|
||||
The Message object also has a `content_type`attribute, which defines the type of the Message. `content_type` can be one of the following strings:
|
||||
'text', 'audio', 'document', 'photo', 'sticker', 'video', 'location', 'contact', 'new_chat_participant', 'left_chat_participant', 'new_chat_title', 'new_chat_photo', 'delete_chat_photo', 'group_chat_created'.
|
||||
The Message object also has a `content_types`attribute, which defines the type of the Message. `content_types` can be one of the following strings:
|
||||
'text', 'audio', 'document', 'photo', 'sticker', 'video', 'voice', 'location', 'contact', 'new_chat_participant', 'left_chat_participant', 'new_chat_title', 'new_chat_photo', 'delete_chat_photo', 'group_chat_created'.
|
||||
|
||||
### Methods
|
||||
|
||||
@ -321,6 +322,33 @@ ForceReply:
|
||||
|
||||

|
||||
|
||||
### Inline Mode
|
||||
|
||||
More information about [Inline mode](https://core.telegram.org/bots/inline).
|
||||
|
||||
#### inline_handler
|
||||
Now, you can use inline_handler to get inline_query in telebot.
|
||||
```python
|
||||
|
||||
@bot.inline_handler(lambda query: query.query == 'text')
|
||||
def query_text(inline_query):
|
||||
# Query message is text
|
||||
```
|
||||
|
||||
#### answer_inline_query
|
||||
|
||||
```python
|
||||
@bot.inline_handler(lambda query: query.query == 'text')
|
||||
def query_text(inline_query):
|
||||
try:
|
||||
r = types.InlineQueryResultArticle('1', 'Result', 'Result message.')
|
||||
r2 = types.InlineQueryResultArticle('2', 'Result2', 'Result message2.')
|
||||
bot.answer_inline_query(inline_query.id, [r, r2])
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
```
|
||||
|
||||
## Advanced use of the API
|
||||
|
||||
### Asynchronous delivery of messages
|
||||
@ -414,8 +442,9 @@ if message.chat.type == “channel”:
|
||||
|
||||
Get help. Discuss. Chat.
|
||||
|
||||
Join the [pyTelegramBotAPI Telegram Chat Group](https://telegram.me/joinchat/067e22c60035523fda8f6025ee87e30b).
|
||||
We now have a Telegram Channel as well! Keep yourself up to date with API changes, and [join it](https://telegram.me/pytelegrambotapi).
|
||||
* Join the pyTelegramBotAPI Telegram Chat Group
|
||||
* Messge to @eternnoir by telegram for Invitation.
|
||||
* We now have a Telegram Channel as well! Keep yourself up to date with API changes, and [join it](https://telegram.me/pytelegrambotapi).
|
||||
|
||||
## More examples
|
||||
|
||||
|
72
examples/inline_example.py
Normal file
72
examples/inline_example.py
Normal file
@ -0,0 +1,72 @@
|
||||
# This example show how to write an inline mode telegramt bot use pyTelegramBotAPI.
|
||||
import telebot
|
||||
import time
|
||||
import sys
|
||||
import logging
|
||||
from telebot import types
|
||||
|
||||
API_TOKEN = '<api_token>'
|
||||
|
||||
bot = telebot.TeleBot(API_TOKEN)
|
||||
telebot.logger.setLevel(logging.DEBUG)
|
||||
|
||||
|
||||
@bot.inline_handler(lambda query: query.query == 'text')
|
||||
def query_text(inline_query):
|
||||
try:
|
||||
r = types.InlineQueryResultArticle('1', 'Result', inline_query.query)
|
||||
r2 = types.InlineQueryResultArticle('2', 'Result2', inline_query.query)
|
||||
bot.answer_inline_query(inline_query.id, [r, r2])
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
|
||||
@bot.inline_handler(lambda query: query.query == 'photo')
|
||||
def query_photo(inline_query):
|
||||
try:
|
||||
r = types.InlineQueryResultPhoto('1',
|
||||
'https://raw.githubusercontent.com/eternnoir/pyTelegramBotAPI/master/examples/detailed_example/kitten.jpg',
|
||||
'https://raw.githubusercontent.com/eternnoir/pyTelegramBotAPI/master/examples/detailed_example/kitten.jpg')
|
||||
r2 = types.InlineQueryResultPhoto('2',
|
||||
'https://raw.githubusercontent.com/eternnoir/pyTelegramBotAPI/master/examples/detailed_example/rooster.jpg',
|
||||
'https://raw.githubusercontent.com/eternnoir/pyTelegramBotAPI/master/examples/detailed_example/rooster.jpg')
|
||||
bot.answer_inline_query(inline_query.id, [r, r2])
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
|
||||
@bot.inline_handler(lambda query: query.query == 'video')
|
||||
def query_video(inline_query):
|
||||
try:
|
||||
r = types.InlineQueryResultVideo('1',
|
||||
'https://github.com/eternnoir/pyTelegramBotAPI/blob/master/tests/test_data/test_video.mp4?raw=true',
|
||||
'video/mp4', 'Video',
|
||||
'https://raw.githubusercontent.com/eternnoir/pyTelegramBotAPI/master/examples/detailed_example/rooster.jpg',
|
||||
'Title'
|
||||
)
|
||||
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)
|
2
setup.py
2
setup.py
@ -6,7 +6,7 @@ def readme():
|
||||
return f.read()
|
||||
|
||||
setup(name='pyTelegramBotAPI',
|
||||
version='1.4.0',
|
||||
version='1.4.1',
|
||||
description='Python Telegram bot api. ',
|
||||
long_description=readme(),
|
||||
author='eternnoir',
|
||||
|
@ -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)
|
||||
@ -44,13 +44,14 @@ class TeleBot:
|
||||
getUpdates
|
||||
"""
|
||||
|
||||
def __init__(self, token, threaded=True):
|
||||
def __init__(self, token, threaded=True, skip_pending=False):
|
||||
"""
|
||||
:param token: bot API token
|
||||
:return: Telebot object.
|
||||
"""
|
||||
self.token = token
|
||||
self.update_listener = []
|
||||
self.skip_pending = skip_pending
|
||||
|
||||
self.__stop_polling = threading.Event()
|
||||
self.last_update_id = 0
|
||||
@ -65,6 +66,8 @@ class TeleBot:
|
||||
self.pre_message_subscribers_next_step = {}
|
||||
|
||||
self.message_handlers = []
|
||||
self.inline_handlers = []
|
||||
self.chosen_inline_handlers = []
|
||||
|
||||
self.threaded = threaded
|
||||
if self.threaded:
|
||||
@ -90,29 +93,64 @@ class TeleBot:
|
||||
ret.append(types.Update.de_json(ju))
|
||||
return ret
|
||||
|
||||
def __skip_updates(self):
|
||||
"""
|
||||
Get and discard all pending updates before first poll of the bot
|
||||
:return: total updates skipped
|
||||
"""
|
||||
total = 0
|
||||
updates = self.get_updates(offset=self.last_update_id, timeout=1)
|
||||
while updates:
|
||||
total += len(updates)
|
||||
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)
|
||||
return total
|
||||
|
||||
def __retrieve_updates(self, timeout=20):
|
||||
"""
|
||||
Retrieves any updates from the Telegram API.
|
||||
Registered listeners and applicable message handlers will be notified when a new message arrives.
|
||||
:raises ApiException when a call has failed.
|
||||
"""
|
||||
if self.skip_pending:
|
||||
logger.debug('Skipped {0} pending messages'.format(self.__skip_updates()))
|
||||
self.skip_pending = False
|
||||
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
|
||||
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)
|
||||
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_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:
|
||||
self.__exec_task(listener, new_messages)
|
||||
@ -141,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):
|
||||
@ -252,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):
|
||||
"""
|
||||
@ -276,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):
|
||||
@ -292,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):
|
||||
"""
|
||||
@ -306,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):
|
||||
"""
|
||||
@ -318,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):
|
||||
"""
|
||||
@ -330,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):
|
||||
"""
|
||||
@ -344,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):
|
||||
"""
|
||||
@ -357,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):
|
||||
"""
|
||||
@ -377,6 +415,19 @@ 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):
|
||||
"""
|
||||
Use this method to send answers to an inline query. On success, True is returned.
|
||||
No more than 50 results per query are allowed.
|
||||
:param inline_query_id: Unique identifier for the answered query
|
||||
:param results: Array of results for the inline query
|
||||
:param cache_time: The maximum amount of time in seconds that the result of the inline query may be cached on the server.
|
||||
:param is_personal: Pass True, if results may be cached on the server side only for the user that sent the query.
|
||||
:param next_offset: Pass the offset that a client should send in the next query with the same text to receive more results.
|
||||
:return: True means success.
|
||||
"""
|
||||
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.
|
||||
@ -397,7 +448,7 @@ class TeleBot:
|
||||
|
||||
def _notify_message_subscribers(self, new_messages):
|
||||
for message in new_messages:
|
||||
if not hasattr(message, 'reply_to_message'):
|
||||
if not message.reply_to_message:
|
||||
continue
|
||||
|
||||
reply_msg_id = message.reply_to_message.message_id
|
||||
@ -485,6 +536,26 @@ class TeleBot:
|
||||
|
||||
return decorator
|
||||
|
||||
def inline_handler(self, func):
|
||||
def decorator(fn):
|
||||
handler_dict = {'function': fn}
|
||||
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']):
|
||||
@ -504,9 +575,9 @@ 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
|
||||
|
@ -42,31 +42,31 @@ 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
|
||||
|
||||
|
||||
def get_me(token):
|
||||
method_url = 'getMe'
|
||||
method_url = r'getMe'
|
||||
return _make_request(token, method_url)
|
||||
|
||||
|
||||
def get_file(token, file_id):
|
||||
method_url = 'getFile'
|
||||
method_url = r'getFile'
|
||||
return _make_request(token, method_url, params={'file_id': file_id})
|
||||
|
||||
|
||||
@ -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
|
||||
@ -106,7 +106,7 @@ def send_message(token, chat_id, text, disable_web_page_preview=None, reply_to_m
|
||||
|
||||
|
||||
def set_webhook(token, url=None, certificate=None):
|
||||
method_url = 'setWebhook'
|
||||
method_url = r'setWebhook'
|
||||
payload = {
|
||||
'url': url if url else "",
|
||||
}
|
||||
@ -253,9 +253,31 @@ def send_data(token, chat_id, data, data_type, reply_to_message_id=None, reply_m
|
||||
|
||||
def get_method_by_type(data_type):
|
||||
if data_type == 'document':
|
||||
return 'sendDocument'
|
||||
return r'sendDocument'
|
||||
if data_type == 'sticker':
|
||||
return 'sendSticker'
|
||||
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):
|
||||
@ -263,6 +285,7 @@ def _convert_markup(markup):
|
||||
return markup.to_json()
|
||||
return markup
|
||||
|
||||
|
||||
class ApiException(Exception):
|
||||
"""
|
||||
This class represents an Exception thrown when a call to the Telegram API fails.
|
||||
|
358
telebot/types.py
358
telebot/types.py
@ -1,24 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Available types
|
||||
|
||||
User
|
||||
GroupChat
|
||||
Message
|
||||
PhotoSize
|
||||
Audio
|
||||
Document
|
||||
Sticker
|
||||
Video
|
||||
Contact
|
||||
Location
|
||||
Update
|
||||
InputFile
|
||||
UserProfilePhotos
|
||||
ReplyKeyboardMarkup
|
||||
ReplyKeyboardHide
|
||||
ForceReply
|
||||
"""
|
||||
|
||||
import json
|
||||
import six
|
||||
@ -87,12 +67,22 @@ 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
|
||||
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):
|
||||
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):
|
||||
@ -233,6 +223,25 @@ class Message(JsonDeserializable):
|
||||
self.from_user = from_user
|
||||
self.message_id = message_id
|
||||
self.content_type = content_type
|
||||
self.forward_from = None
|
||||
self.forward_date = None
|
||||
self.reply_to_message = None
|
||||
self.text = None
|
||||
self.audio = None
|
||||
self.voice = None
|
||||
self.document = None
|
||||
self.photo = None
|
||||
self.sticker = None
|
||||
self.video = None
|
||||
self.location = None
|
||||
self.contact = None
|
||||
self.new_chat_participant = None
|
||||
self.left_chat_participant = None
|
||||
self.new_chat_title = None
|
||||
self.new_chat_photo = None
|
||||
self.delete_chat_photo = None
|
||||
self.group_chat_created = None
|
||||
self.caption = None
|
||||
for key in options:
|
||||
setattr(self, key, options[key])
|
||||
|
||||
@ -496,3 +505,306 @@ 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 = User.de_json(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
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
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):
|
||||
"""
|
||||
Represents a link to an article or web page.
|
||||
:param id: Unique identifier for this result, 1-64 Bytes.
|
||||
:param title: Title of the result.
|
||||
:param message_text: Text of the message to be sent.
|
||||
:param parse_mode: Send “Markdown”, if you want Telegram apps to show bold, italic and inline URLs in your bot's message.
|
||||
:param disable_web_page_preview: Disables link previews for links in the sent message.
|
||||
:param url: URL of the result.
|
||||
:param hide_url: Pass True, if you don't want the URL to be shown in the message.
|
||||
:param description: Short description of the result.
|
||||
:param thumb_url: Url of the thumbnail for the result.
|
||||
:param thumb_width: Thumbnail width.
|
||||
:param thumb_height: Thumbnail height
|
||||
:return:
|
||||
"""
|
||||
self.type = 'article'
|
||||
self.id = id
|
||||
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 = {'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:
|
||||
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)
|
||||
|
||||
|
||||
class InlineQueryResultPhoto(JsonSerializable):
|
||||
def __init__(self, id, photo_url, thumb_url, photo_width=None, photo_height=None, title=None,
|
||||
description=None, caption=None, message_text=None, parse_mode=None, disable_web_page_preview=None):
|
||||
"""
|
||||
Represents a link to a photo.
|
||||
:param id: Unique identifier for this result, 1-64 bytes
|
||||
:param photo_url: A valid URL of the photo. Photo must be in jpeg format. Photo size must not exceed 5MB
|
||||
:param thumb_url: URL of the thumbnail for the photo
|
||||
:param photo_width: Width of the photo.
|
||||
:param photo_height: Height of the photo.
|
||||
:param title: Title for the result.
|
||||
:param description: Short description of the result.
|
||||
:param caption: Caption of the photo to be sent, 0-200 characters.
|
||||
:param message_text: Text of a message to be sent instead of the photo, 1-512 characters.
|
||||
:param parse_mode: Send “Markdown”, if you want Telegram apps to show bold, italic and inline URLs in your bot's message.
|
||||
:param disable_web_page_preview: Disables link previews for links in the sent message.
|
||||
:return:
|
||||
"""
|
||||
self.type = 'photo'
|
||||
self.id = id
|
||||
self.photo_url = photo_url
|
||||
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 = {'type': self.type, 'id': self.id, 'photo_url': self.photo_url, 'thumb_url': self.thumb_url}
|
||||
if self.photo_width:
|
||||
json_dict['photo_width'] = self.photo_width
|
||||
if self.photo_height:
|
||||
json_dict['photo_height'] = self.photo_height
|
||||
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)
|
||||
|
||||
|
||||
class InlineQueryResultGif(JsonSerializable):
|
||||
def __init__(self, id, gif_url, thumb_url, gif_width=None, gif_height=None, title=None, caption=None,
|
||||
message_text=None, parse_mode=None, disable_web_page_preview=None):
|
||||
"""
|
||||
Represents a link to an animated GIF file.
|
||||
:param id: Unique identifier for this result, 1-64 bytes.
|
||||
:param gif_url: A valid URL for the GIF file. File size must not exceed 1MB
|
||||
:param thumb_url: URL of the static thumbnail (jpeg or gif) for the result.
|
||||
:param gif_width: Width of the GIF.
|
||||
:param gif_height: Height of the GIF.
|
||||
:param title: Title for the result.
|
||||
:param caption: Caption of the GIF file to be sent, 0-200 characters
|
||||
:param message_text: Text of a message to be sent instead of the animation, 1-512 characters.
|
||||
:param parse_mode: Send “Markdown”, if you want Telegram apps to show bold, italic and inline URLs in your bot's message.
|
||||
:param disable_web_page_preview: Disables link previews for links in the sent message.
|
||||
:return:
|
||||
"""
|
||||
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, 'thumb_url': self.thumb_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.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)
|
||||
|
||||
|
||||
class InlineQueryResultMpeg4Gif(JsonSerializable):
|
||||
def __init__(self, id, mpeg4_url, thumb_url, mpeg4_width=None, mpeg4_height=None, title=None, caption=None,
|
||||
message_text=None, parse_mode=None, disable_web_page_preview=None):
|
||||
"""
|
||||
Represents a link to a video animation (H.264/MPEG-4 AVC video without sound).
|
||||
:param id: Unique identifier for this result, 1-64 bytes
|
||||
:param mpeg4_url: A valid URL for the MP4 file. File size must not exceed 1MB
|
||||
:param thumb_url: URL of the static thumbnail (jpeg or gif) for the result
|
||||
:param mpeg4_width: Video width
|
||||
:param mpeg4_height: Video height
|
||||
:param title: Title for the result
|
||||
:param caption: Caption of the MPEG-4 file to be sent, 0-200 characters
|
||||
:param message_text: Text of a message to be sent instead of the animation, 1-512 characters
|
||||
:param parse_mode: end “Markdown”, if you want Telegram apps to show bold, italic and inline URLs in your bot's message.
|
||||
:param disable_web_page_preview: Disables link previews for links in the sent message
|
||||
:return:
|
||||
"""
|
||||
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, 'thumb_url': self.thumb_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.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)
|
||||
|
||||
|
||||
class InlineQueryResultVideo(JsonSerializable):
|
||||
def __init__(self, id, video_url, mime_type, message_text, thumb_url, title, parse_mode=None,
|
||||
disable_web_page_preview=None,
|
||||
video_width=None, video_height=None, video_duration=None,
|
||||
description=None):
|
||||
"""
|
||||
Represents link to a page containing an embedded video player or a video file.
|
||||
:param id: Unique identifier for this result, 1-64 bytes
|
||||
:param video_url: A valid URL for the embedded video player or video file
|
||||
:param mime_type: Mime type of the content of video url, “text/html” or “video/mp4”
|
||||
:param message_text: Text of the message to be sent with the video, 1-512 characters
|
||||
:param thumb_url: URL of the thumbnail (jpeg only) for the video
|
||||
:param title: Title for the result
|
||||
:param parse_mode: Send “Markdown”, if you want Telegram apps to show bold, italic and inline URLs in your bot's message.
|
||||
:param disable_web_page_preview: Disables link previews for links in the sent message
|
||||
:param video_width: Video width
|
||||
:param video_height: Video height
|
||||
:param video_duration: Video duration in seconds
|
||||
:param description: Short description of the result
|
||||
:return:
|
||||
"""
|
||||
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,
|
||||
'message_text': self.message_text, 'thumb_url': self.thumb_url, 'title': self.title}
|
||||
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.description:
|
||||
json_dict['description'] = self.description
|
||||
return json.dumps(json_dict)
|
||||
|
Reference in New Issue
Block a user