mirror of
https://github.com/eternnoir/pyTelegramBotAPI.git
synced 2023-08-10 21:12:57 +03:00
commit
288bb95553
126
README.md
126
README.md
@ -1,12 +1,13 @@
|
||||
# pyTelegramBotAPI
|
||||
|
||||
Python Telegram Bot API.
|
||||
A Python implementation for the Telegram Bot API.
|
||||
|
||||
[https://core.telegram.org/bots/api](https://core.telegram.org/bots/api)
|
||||
See [https://core.telegram.org/bots/api](https://core.telegram.org/bots/api)
|
||||
|
||||
## How to install
|
||||
|
||||
* Need python2 or python3
|
||||
Python 2 or Python 3 is required.
|
||||
|
||||
* Install from source
|
||||
|
||||
```
|
||||
@ -15,7 +16,7 @@ $ cd pyTelegramBotAPI
|
||||
$ python setup.py install
|
||||
```
|
||||
|
||||
* or install by pip
|
||||
* or install with pip
|
||||
|
||||
```
|
||||
$ pip install pyTelegramBotAPI
|
||||
@ -23,7 +24,7 @@ $ pip install pyTelegramBotAPI
|
||||
|
||||
## Example
|
||||
|
||||
* Send Message
|
||||
* Sending a message.
|
||||
|
||||
```python
|
||||
import telebot
|
||||
@ -31,8 +32,8 @@ import telebot
|
||||
TOKEN = '<token string>'
|
||||
|
||||
tb = telebot.TeleBot(TOKEN)
|
||||
# tb.send_message(chatid,message)
|
||||
print tb.send_message(281281, 'gogo power ranger')
|
||||
# tb.send_message(chatid, message)
|
||||
tb.send_message(281281, 'gogo power ranger')
|
||||
```
|
||||
|
||||
* Echo Bot
|
||||
@ -45,23 +46,21 @@ TOKEN = '<token_string>'
|
||||
|
||||
def listener(*messages):
|
||||
"""
|
||||
When new message get will call this function.
|
||||
:param messages:
|
||||
:return:
|
||||
When new messages arrive TeleBot will call this function.
|
||||
"""
|
||||
for m in messages:
|
||||
chatid = m.chat.id
|
||||
if m.content_type == 'text'
|
||||
if m.content_type == 'text':
|
||||
text = m.text
|
||||
tb.send_message(chatid, text)
|
||||
|
||||
|
||||
tb = telebot.TeleBot(TOKEN)
|
||||
tb.get_update() # cache exist message
|
||||
tb.set_update_listener(listener) #register listener
|
||||
tb.polling(3)
|
||||
while True:
|
||||
time.sleep(20)
|
||||
tb.polling()
|
||||
|
||||
while True: # Don't let the main Thread end.
|
||||
pass
|
||||
```
|
||||
|
||||
## TeleBot API usage
|
||||
@ -71,7 +70,7 @@ import telebot
|
||||
import time
|
||||
|
||||
TOKEN = '<token_string>'
|
||||
tb = telebot.TeleBot(TOKEN) #create new Telegram Bot object
|
||||
tb = telebot.TeleBot(TOKEN) #create a new Telegram Bot object
|
||||
|
||||
# getMe
|
||||
user = tb.get_me()
|
||||
@ -107,43 +106,59 @@ tb.send_video(chat_id, video)
|
||||
tb.send_location(chat_id, lat, lon)
|
||||
|
||||
# sendChatAction
|
||||
# action_string can be : typing,upload_photo,record_video,upload_video,record_audio,upload_audio,upload_document,
|
||||
# find_location.
|
||||
# action_string can be one of the following strings: 'typing', 'upload_photo', 'record_video', 'upload_video',
|
||||
# 'record_audio', 'upload_audio', 'upload_document' or 'find_location'.
|
||||
tb.send_chat_action(chat_id, action_string)
|
||||
|
||||
# ReplyKeyboardMarkup.
|
||||
# Use ReplyKeyboardMarkup class.
|
||||
# Use the ReplyKeyboardMarkup class.
|
||||
# Thanks pevdh.
|
||||
|
||||
from telebot import types
|
||||
|
||||
markup = types.ReplyKeyboardMarkup()
|
||||
markup.add('a', 'v', 'd')
|
||||
tb.send_message(chat_id, message, None, None, markup)
|
||||
# or use row method
|
||||
tb.send_message(chat_id, message, reply_markup=markup)
|
||||
|
||||
# or add strings one row at a time:
|
||||
markup = types.ReplyKeyboardMarkup()
|
||||
markup.row('a', 'v')
|
||||
markup.row('c', 'd', 'e')
|
||||
tb.send_message(chat_id, message, None, None, markup)
|
||||
tb.send_message(chat_id, message, reply_markup=markup)
|
||||
|
||||
```
|
||||
|
||||
## Message notifier
|
||||
|
||||
* Define listener function
|
||||
|
||||
## Creating a Telegram bot with the pyTelegramBotAPI
|
||||
There are two ways to define a Telegram Bot with the pyTelegramBotAPI.
|
||||
### The listener mechanism
|
||||
* First, create a TeleBot instance.
|
||||
```python
|
||||
def listener1(*messages):
|
||||
import telebot
|
||||
|
||||
TOKEN = '<token string>'
|
||||
|
||||
bot = telebot.TeleBot(TOKEN)
|
||||
```
|
||||
* Then, define a listener function.
|
||||
```python
|
||||
def echo_messages(*messages):
|
||||
"""
|
||||
Echoes all incoming messages of content_type 'text'.
|
||||
"""
|
||||
for m in messages:
|
||||
chatid = m.chat.id
|
||||
if m.content_type == 'text'
|
||||
if m.content_type == 'text':
|
||||
text = m.text
|
||||
tb.send_message(chatid, text)
|
||||
bot.send_message(chatid, text)
|
||||
```
|
||||
* Now, register your listener with the TeleBot instance and call TeleBot#polling()
|
||||
```python
|
||||
bot.set_update_listener(echo_messages)
|
||||
bot.polling()
|
||||
|
||||
* Use ***set_update_listener*** method to add listener function to telebot.
|
||||
* Start polling or call get_update(). If get new updates, telebot will call listener and pass messages to listener.
|
||||
* use Message's content_type attribute to check message type. Now Message support content_type:
|
||||
while True: # Don't let the main Thread end.
|
||||
pass
|
||||
```
|
||||
* use Message's content_type attribute to check the type of Message. Now Message supports content types:
|
||||
* text
|
||||
* audio
|
||||
* document
|
||||
@ -151,6 +166,49 @@ def listener1(*messages):
|
||||
* sticker
|
||||
* video
|
||||
* location
|
||||
* That's it!
|
||||
|
||||
### The decorator mechanism
|
||||
* First, create a TeleBot instance.
|
||||
```python
|
||||
import telebot
|
||||
|
||||
TOKEN = '<token string>'
|
||||
|
||||
bot = telebot.TeleBot(TOKEN)
|
||||
```
|
||||
* Next, define all of your so-called message handlers and decorate them with @bot.message_handler
|
||||
```python
|
||||
# Handle /start and /help
|
||||
@bot.message_handler(commands=['start', 'help'])
|
||||
def command_help(message):
|
||||
bot.reply_to(message, "Hello, did someone call for help?")
|
||||
|
||||
# Handles all messages which text matches the regex regexp.
|
||||
# See https://en.wikipedia.org/wiki/Regular_expression
|
||||
# This regex matches all sent url's.
|
||||
@bot.message_handler(regexp='((https?):((//)|(\\\\))+([\w\d:#@%/;$()~_?\+-=\\\.&](#!)?)*)')
|
||||
def command_url(message):
|
||||
bot.reply_to(message, "I shouldn't open that url, should I?")
|
||||
|
||||
# Handle all sent documents of type 'text/plain'.
|
||||
@bot.message_handler(func=lambda message: message.document.mime_type == 'text/plain', content_types=['document'])
|
||||
def command_handle_document(message):
|
||||
bot.reply_to(message, "Document received, sir!")
|
||||
|
||||
# Default command handler. A lambda expression which always returns True is used for this purpose.
|
||||
@bot.message_handler(func=lambda message: True, content_types=['audio', 'video', 'document', 'text', 'location', 'contact', 'sticker'])
|
||||
def default_command(message):
|
||||
bot.reply_to(message, "This is the default command handler.")
|
||||
```
|
||||
* And finally, call bot.polling()
|
||||
```python
|
||||
bot.polling()
|
||||
|
||||
while True: # Don't end the main thread.
|
||||
pass
|
||||
```
|
||||
Use whichever mechanism fits your purpose! It is even possible to mix and match.
|
||||
|
||||
## TODO
|
||||
|
||||
@ -165,4 +223,4 @@ def listener1(*messages):
|
||||
- [x] sendLocation
|
||||
- [x] sendChatAction
|
||||
- [x] getUserProfilePhotos
|
||||
- [ ] getUpdat(chat message not yet)
|
||||
- [ ] getUpdate(chat message not yet)
|
||||
|
28
examples/echo_bot.py
Normal file
28
examples/echo_bot.py
Normal file
@ -0,0 +1,28 @@
|
||||
# This is a simple echo bot using the decorator mechanism.
|
||||
# It echoes any incoming text messages.
|
||||
|
||||
import telebot
|
||||
|
||||
API_TOKEN = '<api_token>'
|
||||
|
||||
bot = telebot.TeleBot(API_TOKEN)
|
||||
|
||||
|
||||
# Handle '/start' and '/help'
|
||||
@bot.message_handler(commands=['help, start'])
|
||||
def send_welcome(message):
|
||||
bot.reply_to(message, """\
|
||||
Hi there, I am EchoBot.
|
||||
I am here to echo your kind words back to you. Just say anything nice and I'll say the exact same thing to you!\
|
||||
""")
|
||||
|
||||
|
||||
# Handle all other messages with content_type 'text' (content_types defaults to ['text'])
|
||||
@bot.message_handler(func=lambda message: True)
|
||||
def echo_message(message):
|
||||
bot.reply_to(message, message.text)
|
||||
|
||||
bot.polling()
|
||||
|
||||
while True:
|
||||
pass
|
@ -41,7 +41,7 @@ class TeleBot:
|
||||
|
||||
self.last_update_id = 0
|
||||
|
||||
self.commands = []
|
||||
self.message_handlers = []
|
||||
|
||||
def get_update(self):
|
||||
"""
|
||||
@ -49,7 +49,7 @@ class TeleBot:
|
||||
Registered listeners and applicable message handlers will be notified when a new message arrives.
|
||||
:raises ApiException when a call has failed.
|
||||
"""
|
||||
updates = apihelper.get_updates(self.token, offset=(self.last_update_id + 1))
|
||||
updates = apihelper.get_updates(self.token, offset=(self.last_update_id + 1), timeout=20)
|
||||
new_messages = []
|
||||
for update in updates:
|
||||
if update['update_id'] > self.last_update_id:
|
||||
@ -66,31 +66,32 @@ class TeleBot:
|
||||
t = threading.Thread(target=listener, args=new_messages)
|
||||
t.start()
|
||||
|
||||
def polling(self, interval=3):
|
||||
def polling(self):
|
||||
"""
|
||||
This function creates a new Thread that calls an internal __polling function.
|
||||
This allows the bot to retrieve Updates automagically and notify listeners and message handlers accordingly.
|
||||
|
||||
Do not call this function more than once!
|
||||
|
||||
Always get updates.
|
||||
:param interval: interval secs.
|
||||
:return:
|
||||
"""
|
||||
self.interval = interval
|
||||
# clear thread.
|
||||
self.__stop_polling = True
|
||||
time.sleep(interval + 1)
|
||||
self.__stop_polling = False
|
||||
self.polling_thread = threading.Thread(target=self.__polling, args=())
|
||||
self.polling_thread.daemon = True
|
||||
self.polling_thread.start()
|
||||
|
||||
def __polling(self):
|
||||
print('telegram bot start polling')
|
||||
print('TeleBot: Started polling.')
|
||||
while not self.__stop_polling:
|
||||
try:
|
||||
self.get_update()
|
||||
except Exception as e:
|
||||
print("TeleBot: Exception occurred. Stopping.")
|
||||
self.__stop_polling = True
|
||||
print(e)
|
||||
time.sleep(self.interval)
|
||||
|
||||
print('telegram bot stop polling')
|
||||
print('TeleBot: Stopped polling.')
|
||||
|
||||
def stop_polling(self):
|
||||
self.__stop_polling = True
|
||||
@ -109,7 +110,7 @@ class TeleBot:
|
||||
:param user_id:
|
||||
:param offset:
|
||||
:param limit:
|
||||
:return:
|
||||
:return: API reply.
|
||||
"""
|
||||
result = apihelper.get_user_profile_photos(self.token, user_id, offset, limit)
|
||||
return types.UserProfilePhotos.de_json(result)
|
||||
@ -122,10 +123,11 @@ class TeleBot:
|
||||
:param disable_web_page_preview:
|
||||
:param reply_to_message_id:
|
||||
:param reply_markup:
|
||||
:return:
|
||||
:return: API reply.
|
||||
"""
|
||||
return apihelper.send_message(self.token, chat_id, text, disable_web_page_preview, reply_to_message_id,
|
||||
reply_markup)
|
||||
return types.Message.de_json(
|
||||
apihelper.send_message(self.token, chat_id, text, disable_web_page_preview, reply_to_message_id,
|
||||
reply_markup))
|
||||
|
||||
def forward_message(self, chat_id, from_chat_id, message_id):
|
||||
"""
|
||||
@ -133,9 +135,9 @@ class TeleBot:
|
||||
:param chat_id: which chat to forward
|
||||
:param from_chat_id: which chat message from
|
||||
:param message_id: message id
|
||||
:return:
|
||||
:return: API reply.
|
||||
"""
|
||||
return apihelper.forward_message(self.token, chat_id, from_chat_id, message_id)
|
||||
return types.Message.de_json(apihelper.forward_message(self.token, chat_id, from_chat_id, message_id))
|
||||
|
||||
def send_photo(self, chat_id, photo, caption=None, reply_to_message_id=None, reply_markup=None):
|
||||
"""
|
||||
@ -145,9 +147,10 @@ class TeleBot:
|
||||
:param caption:
|
||||
:param reply_to_message_id:
|
||||
:param reply_markup:
|
||||
:return:
|
||||
:return: API reply.
|
||||
"""
|
||||
return apihelper.send_photo(self.token, chat_id, photo, caption, reply_to_message_id, reply_markup)
|
||||
return types.Message.de_json(
|
||||
apihelper.send_photo(self.token, chat_id, photo, caption, reply_to_message_id, reply_markup))
|
||||
|
||||
def send_audio(self, chat_id, data, reply_to_message_id=None, reply_markup=None):
|
||||
"""
|
||||
@ -157,9 +160,10 @@ class TeleBot:
|
||||
:param data:
|
||||
:param reply_to_message_id:
|
||||
:param reply_markup:
|
||||
:return:
|
||||
:return: API reply.
|
||||
"""
|
||||
return apihelper.send_data(self.token, chat_id, data, 'audio', reply_to_message_id, reply_markup)
|
||||
return types.Message.de_json(
|
||||
apihelper.send_data(self.token, chat_id, data, 'audio', reply_to_message_id, reply_markup))
|
||||
|
||||
def send_document(self, chat_id, data, reply_to_message_id=None, reply_markup=None):
|
||||
"""
|
||||
@ -168,9 +172,10 @@ class TeleBot:
|
||||
:param data:
|
||||
:param reply_to_message_id:
|
||||
:param reply_markup:
|
||||
:return:
|
||||
:return: API reply.
|
||||
"""
|
||||
return apihelper.send_data(self.token, chat_id, data, 'document', reply_to_message_id, reply_markup)
|
||||
return types.Message.de_json(
|
||||
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):
|
||||
"""
|
||||
@ -179,9 +184,10 @@ class TeleBot:
|
||||
:param data:
|
||||
:param reply_to_message_id:
|
||||
:param reply_markup:
|
||||
:return:
|
||||
:return: API reply.
|
||||
"""
|
||||
return apihelper.send_data(self.token, chat_id, data, 'sticker', reply_to_message_id, reply_markup)
|
||||
return types.Message.de_json(
|
||||
apihelper.send_data(self.token, chat_id, data, 'sticker', reply_to_message_id, reply_markup))
|
||||
|
||||
def send_video(self, chat_id, data, reply_to_message_id=None, reply_markup=None):
|
||||
"""
|
||||
@ -190,9 +196,10 @@ class TeleBot:
|
||||
:param data:
|
||||
:param reply_to_message_id:
|
||||
:param reply_markup:
|
||||
:return:
|
||||
:return: API reply.
|
||||
"""
|
||||
return apihelper.send_data(self.token, chat_id, data, 'video', reply_to_message_id, reply_markup)
|
||||
return types.Message.de_json(
|
||||
apihelper.send_data(self.token, chat_id, data, 'video', reply_to_message_id, reply_markup))
|
||||
|
||||
def send_location(self, chat_id, latitude, longitude, reply_to_message_id=None, reply_markup=None):
|
||||
"""
|
||||
@ -202,9 +209,10 @@ class TeleBot:
|
||||
:param longitude:
|
||||
:param reply_to_message_id:
|
||||
:param reply_markup:
|
||||
:return:
|
||||
:return: API reply.
|
||||
"""
|
||||
return apihelper.send_location(self.token, chat_id, latitude, longitude, reply_to_message_id, reply_markup)
|
||||
return types.Message.de_json(
|
||||
apihelper.send_location(self.token, chat_id, latitude, longitude, reply_to_message_id, reply_markup))
|
||||
|
||||
def send_chat_action(self, chat_id, action):
|
||||
"""
|
||||
@ -212,13 +220,16 @@ class TeleBot:
|
||||
The status is set for 5 seconds or less (when a message arrives from your bot, Telegram clients clear
|
||||
its typing status).
|
||||
:param chat_id:
|
||||
:param action: string . typing,upload_photo,record_video,upload_video,record_audio,upload_audio,upload_document,
|
||||
find_location.
|
||||
:return:
|
||||
:param action: One of the following strings: 'typing', 'upload_photo', 'record_video', 'upload_video',
|
||||
'record_audio', 'upload_audio', 'upload_document', 'find_location'.
|
||||
:return: API reply.
|
||||
"""
|
||||
return apihelper.send_chat_action(self.token, chat_id, action)
|
||||
return types.Message.de_json(apihelper.send_chat_action(self.token, chat_id, action))
|
||||
|
||||
def message_handler(self, regexp=None, func=None, content_types=['text']):
|
||||
def reply_to(self, message, text, **kwargs):
|
||||
return self.send_message(message.chat.id, text, reply_to_message_id=message.message_id, **kwargs)
|
||||
|
||||
def message_handler(self, commands=None, regexp=None, func=None, content_types=['text']):
|
||||
"""
|
||||
Message handler decorator.
|
||||
This decorator can be used to decorate functions that must handle certain types of messages.
|
||||
@ -246,27 +257,148 @@ class TeleBot:
|
||||
:param regexp: Optional regular expression.
|
||||
:param func: Optional lambda function. The lambda receives the message to test as the first parameter. It must return True if the command should handle the message.
|
||||
:param content_types: This commands' supported content types. Must be a list. Defaults to ['text'].
|
||||
:return:
|
||||
"""
|
||||
|
||||
def decorator(fn):
|
||||
self.commands.append([fn, regexp, func, content_types])
|
||||
func_dict = {'function': fn, 'content_types': content_types}
|
||||
if regexp:
|
||||
func_dict['regexp'] = regexp if 'text' in content_types else None
|
||||
if func:
|
||||
func_dict['lambda'] = func
|
||||
if commands:
|
||||
func_dict['commands'] = commands if 'text' in content_types else None
|
||||
self.message_handlers.append(func_dict)
|
||||
return fn
|
||||
|
||||
return decorator
|
||||
|
||||
@staticmethod
|
||||
def _test_command(command, message):
|
||||
if message.content_type not in command[3]:
|
||||
def is_command(text):
|
||||
"""
|
||||
Checks if `text` is a command. Telegram chat commands start with the '/' character.
|
||||
:param text: Text to check.
|
||||
:return: True if `text` is a command, else False.
|
||||
"""
|
||||
return text.startswith('/')
|
||||
|
||||
@staticmethod
|
||||
def extract_command(text):
|
||||
"""
|
||||
Extracts the command from `text` (minus the '/') if `text` is a command (see is_command).
|
||||
If `text` is not a command, this function returns None.
|
||||
|
||||
Examples:
|
||||
extract_command('/help'): 'help'
|
||||
extract_command('/search black eyed peas'): 'search'
|
||||
extract_command('Good day to you'): None
|
||||
|
||||
:param text: String to extract the command from
|
||||
:return: the command if `text` is a command, else None.
|
||||
"""
|
||||
return text.split()[0][1:] if TeleBot.is_command(text) else None
|
||||
|
||||
@staticmethod
|
||||
def _test_message_handler(message_handler, message):
|
||||
if message.content_type not in message_handler['content_types']:
|
||||
return False
|
||||
if command[1] is not None and message.content_type == 'text' and re.search(command[1], message.text):
|
||||
return True
|
||||
if command[2] is not None:
|
||||
return command[2](message)
|
||||
if 'commands' in message_handler and message.content_type == 'text':
|
||||
return TeleBot.extract_command(message.text) in message_handler['commands']
|
||||
if 'regexp' in message_handler and message.content_type == 'text' and re.search(message_handler['regexp'],
|
||||
message.text):
|
||||
return False
|
||||
if 'lambda' in message_handler:
|
||||
return message_handler['lambda'](message)
|
||||
return False
|
||||
|
||||
def _notify_command_handlers(self, new_messages):
|
||||
for message in new_messages:
|
||||
for command in self.commands:
|
||||
if self._test_command(command, message):
|
||||
t = threading.Thread(target=command[0], args=(message,))
|
||||
for message_handler in self.message_handlers:
|
||||
if self._test_message_handler(message_handler, message):
|
||||
t = threading.Thread(target=message_handler['function'], args=(message,))
|
||||
t.start()
|
||||
break
|
||||
|
||||
|
||||
class AsyncTask:
|
||||
def __init__(self, target, *args, **kwargs):
|
||||
self.target = target
|
||||
self.args = args
|
||||
self.kwargs = kwargs
|
||||
|
||||
self.done = False
|
||||
self.thread = threading.Thread(target=self._run)
|
||||
self.thread.start()
|
||||
|
||||
def _run(self):
|
||||
try:
|
||||
self.result = self.target(*self.args, **self.kwargs)
|
||||
except Exception as e:
|
||||
self.result = e
|
||||
self.done = True
|
||||
|
||||
def wait(self):
|
||||
if not self.done:
|
||||
self.thread.join()
|
||||
if isinstance(self.result, Exception):
|
||||
raise self.result
|
||||
else:
|
||||
return self.result
|
||||
|
||||
|
||||
def async():
|
||||
def decorator(fn):
|
||||
def wrapper(*args, **kwargs):
|
||||
return AsyncTask(fn, *args, **kwargs)
|
||||
|
||||
return wrapper
|
||||
|
||||
return decorator
|
||||
|
||||
|
||||
class AsyncTeleBot(TeleBot):
|
||||
def __init__(self, *args, **kwargs):
|
||||
TeleBot.__init__(self, *args, **kwargs)
|
||||
|
||||
@async()
|
||||
def get_me(self):
|
||||
return TeleBot.get_me(self)
|
||||
|
||||
@async()
|
||||
def get_user_profile_photos(self, *args, **kwargs):
|
||||
return TeleBot.get_user_profile_photos(self, *args, **kwargs)
|
||||
|
||||
@async()
|
||||
def send_message(self, *args, **kwargs):
|
||||
return TeleBot.send_message(self, *args, **kwargs)
|
||||
|
||||
@async()
|
||||
def forward_message(self, *args, **kwargs):
|
||||
return TeleBot.forward_message(self, *args, **kwargs)
|
||||
|
||||
@async()
|
||||
def send_photo(self, *args, **kwargs):
|
||||
return TeleBot.send_photo(self, *args, **kwargs)
|
||||
|
||||
@async()
|
||||
def send_audio(self, *args, **kwargs):
|
||||
return TeleBot.send_audio(self, *args, **kwargs)
|
||||
|
||||
@async()
|
||||
def send_document(self, *args, **kwargs):
|
||||
return TeleBot.send_document(self, *args, **kwargs)
|
||||
|
||||
@async()
|
||||
def send_sticker(self, *args, **kwargs):
|
||||
return TeleBot.send_sticker(self, *args, **kwargs)
|
||||
|
||||
@async()
|
||||
def send_video(self, *args, **kwargs):
|
||||
return TeleBot.send_video(self, *args, **kwargs)
|
||||
|
||||
@async()
|
||||
def send_location(self, *args, **kwargs):
|
||||
return TeleBot.send_location(self, *args, **kwargs)
|
||||
|
||||
@async()
|
||||
def send_chat_action(self, *args, **kwargs):
|
||||
return TeleBot.send_chat_action(self, *args, **kwargs)
|
||||
|
@ -56,12 +56,16 @@ def send_message(token, chat_id, text, disable_web_page_preview=None, reply_to_m
|
||||
return _make_request(token, method_url, params=payload)
|
||||
|
||||
|
||||
def get_updates(token, offset=None):
|
||||
def get_updates(token, offset=None, limit=None, timeout=None):
|
||||
method_url = r'getUpdates'
|
||||
if offset is not None:
|
||||
return _make_request(token, method_url, params={'offset': offset})
|
||||
else:
|
||||
return _make_request(token, method_url)
|
||||
payload = {}
|
||||
if offset:
|
||||
payload['offset'] = offset
|
||||
if limit:
|
||||
payload['limit'] = limit
|
||||
if timeout:
|
||||
payload['timeout'] = timeout
|
||||
return _make_request(token, method_url, params=payload)
|
||||
|
||||
|
||||
def get_user_profile_photos(token, user_id, offset=None, limit=None):
|
||||
|
@ -290,6 +290,7 @@ class Contact(JsonDeserializable):
|
||||
phone_number = obj['phone_number']
|
||||
first_name = obj['first_name']
|
||||
last_name = None
|
||||
user_id = None
|
||||
if 'last_name' in obj:
|
||||
last_name = obj['last_name']
|
||||
if 'user_id' in obj:
|
||||
|
Loading…
Reference in New Issue
Block a user