1
0
mirror of https://github.com/eternnoir/pyTelegramBotAPI.git synced 2023-08-10 21:12:57 +03:00

Compare commits

..

19 Commits
3.1.0 ... 3.2.0

Author SHA1 Message Date
dcddedcd24 Fix file dic. 2017-08-06 15:35:43 +08:00
2e743b4b86 Add v3.2 method. 2017-08-06 15:22:23 +08:00
af70313721 New method for v3.2 2017-08-06 14:25:25 +08:00
aefd666062 Update sticker set. 2017-08-06 12:00:26 +08:00
23d66afbb0 Merge pull request #381 from noirgif/master
change the documentation of TeleBot.polling in readme
2017-08-01 09:31:01 +08:00
ed29f9316f change the documentation of TeleBot.polling in readme 2017-07-30 23:24:30 -07:00
c91ce6036b Merge pull request #372 from Kylmakalle/master
Async Methods for API v3.1
2017-07-23 15:50:02 +08:00
cb60a1256f Merge pull request #374 from the31k/per_thread_requests_sessions
Per-thread requests sessions
2017-07-23 15:49:42 +08:00
96569cbdac Fix typo 2017-07-19 15:44:10 +03:00
feec19b7f4 Use per-thread requests sessions
Reason is requests.Session is not thread-safe
See: https://github.com/requests/requests/issues/2766
2017-07-19 01:50:12 +03:00
1a80fc5a0e Per-thread singletons 2017-07-19 01:50:04 +03:00
488fb745b7 Merge pull request #359 from Yolley/master
Informative exception message for better exception handling
2017-07-07 10:45:23 +08:00
08d6ab549d Aync Methods for v3.1 2017-07-07 00:54:18 +03:00
f718c36ea7 Merge remote-tracking branch 'refs/remotes/eternnoir/master' 2017-07-07 00:29:40 +03:00
ed88939110 Merge remote-tracking branch 'refs/remotes/eternnoir/master' 2017-07-07 00:25:13 +03:00
0632cfb9b0 Fix new chat members. 2017-07-02 21:24:19 +08:00
4979589faf Fix not require args. #369 2017-07-02 21:08:36 +08:00
242456d92b Update util.py 2017-06-20 15:45:18 +03:00
328cabead6 Update util.py 2017-06-20 15:45:01 +03:00
7 changed files with 351 additions and 36 deletions

View File

@ -234,8 +234,8 @@ tb = telebot.TeleBot(TOKEN) #create a new Telegram Bot object
# - none_stop: True/False (default False) - Don't stop polling when receiving an error from the Telegram servers
# - interval: True/False (default False) - The interval between polling requests
# Note: Editing this parameter harms the bot's response time
# - block: True/False (default True) - Blocks upon calling this function
tb.polling(none_stop=False, interval=0, block=True)
# - timeout: integer (default 20) - Timeout in seconds for long polling.
tb.polling(none_stop=False, interval=0, timeout=20)
# getMe
user = tb.get_me()

View File

@ -421,8 +421,8 @@ TeleBot
# - none_stop: True/False (default False) - Don't stop polling when receiving an error from the Telegram servers
# - interval: True/False (default False) - The interval between polling requests
# Note: Editing this parameter harms the bot's response time
# - block: True/False (default True) - Blocks upon calling this function
tb.polling(none_stop=False, interval=0, block=True)
# - timeout: integer (default 20) - Timeout in seconds for long polling.
tb.polling(none_stop=False, interval=0, timeout=20)
# getMe
user = tb.get_me()

View File

@ -7,7 +7,7 @@ def readme():
return f.read()
setup(name='pyTelegramBotAPI',
version='3.1.0',
version='3.1.1',
description='Python Telegram bot api. ',
long_description=readme(),
author='eternnoir',

View File

@ -255,6 +255,7 @@ class TeleBot:
Warning: Do not call this function more than once!
Always get updates.
:param interval:
:param none_stop: Do not stop polling when an ApiException occurs.
:param timeout: Timeout in seconds for long polling.
:return:
@ -462,6 +463,7 @@ class TeleBot:
disable_notification=None):
"""
Use this method to send photos.
:param disable_notification:
:param chat_id:
:param photo:
:param caption:
@ -634,9 +636,9 @@ class TeleBot:
def unban_chat_member(self, chat_id, user_id):
return apihelper.unban_chat_member(self.token, chat_id, user_id)
def restrict_chat_member(self, chat_id, user_id, until_date=None, can_send_messages=True,
can_send_media_messages=True, can_send_other_messages=True,
can_add_web_page_previews=True):
def restrict_chat_member(self, chat_id, user_id, until_date=None, can_send_messages=None,
can_send_media_messages=None, can_send_other_messages=None,
can_add_web_page_previews=None):
"""
Use this method to restrict a user in a supergroup.
The bot must be an administrator in the supergroup for this to work and must have
@ -661,9 +663,9 @@ class TeleBot:
can_send_media_messages, can_send_other_messages,
can_add_web_page_previews)
def promote_chat_member(self, chat_id, user_id, can_change_info=False, can_post_messages=False,
can_edit_messages=False, can_delete_messages=False, can_invite_users=False,
can_restrict_members=False, can_pin_messages=False, can_promote_members=False):
def promote_chat_member(self, chat_id, user_id, can_change_info=None, can_post_messages=None,
can_edit_messages=None, can_delete_messages=None, can_invite_users=None,
can_restrict_members=None, can_pin_messages=None, can_promote_members=None):
"""
Use this method to promote or demote a user in a supergroup or a channel. The bot must be an administrator
in the chat for this to work and must have the appropriate admin rights.
@ -871,6 +873,86 @@ class TeleBot:
"""
return apihelper.answer_callback_query(self.token, callback_query_id, text, show_alert, url, cache_time)
# def send_sticker(self, chat_id, sticker, disable_notification=None, reply_to_message_id=None, reply_markup=None):
# """
# Use this method to send .webp stickers. On success, the sent Message is returned.
# :param chat_id:
# :param sticker:
# :param disable_notification:
# :param reply_to_message_id:
# :param reply_markup:
# :return:
# """
# result = apihelper.send_sticker(self.token, chat_id, sticker, disable_notification, reply_markup, reply_markup)
# return types.Message.de_json(result)
def get_sticker_set(self, name):
"""
Use this method to get a sticker set. On success, a StickerSet object is returned.
:param token:
:param name:
:return:
"""
result = apihelper.get_sticker_set(self.token, name)
return types.StickerSet.de_json(result)
def upload_sticker_file(self, user_id, png_sticker):
"""
Use this method to upload a .png file with a sticker for later use in createNewStickerSet and addStickerToSet
methods (can be used multiple times). Returns the uploaded File on success.
:param user_id:
:param png_sticker:
:return:
"""
result = apihelper.upload_sticker_file(self.token, user_id, png_sticker)
return types.File.de_json(result)
def create_new_sticker_set(self, user_id, name, title, png_sticker, emojis, contains_masks=None,
mask_position=None):
"""
Use this method to create new sticker set owned by a user. The bot will be able to edit the created sticker set.
Returns True on success.
:param user_id:
:param name:
:param title:
:param png_sticker:
:param emojis:
:param contains_masks:
:param mask_position:
:return:
"""
return apihelper.create_new_sticker_set(self.token, user_id, name, title, png_sticker, emojis, contains_masks,
mask_position)
def add_sticker_to_set(self, user_id, name, png_sticker, emojis, mask_position):
"""
Use this method to add a new sticker to a set created by the bot. Returns True on success.
:param user_id:
:param name:
:param png_sticker:
:param emojis:
:param mask_position:
:return:
"""
return apihelper.add_sticker_to_set(self.token, user_id, name, png_sticker, emojis, mask_position)
def set_sticker_position_in_set(self, sticker, position):
"""
Use this method to move a sticker in a set created by the bot to a specific position . Returns True on success.
:param sticker:
:param position:
:return:
"""
return apihelper.set_sticker_position_in_set(self.token, sticker, position)
def delete_sticker_from_set(self, sticker):
"""
Use this method to delete a sticker from a set created by the bot. Returns True on success.
:param sticker:
:return:
"""
return apihelper.delete_sticker_from_set(self.token, sticker)
def register_for_reply(self, message, callback):
"""
Registers a callback function to be notified when a reply to `message` arrives.
@ -1215,13 +1297,49 @@ class AsyncTeleBot(TeleBot):
return TeleBot.send_chat_action(self, *args, **kwargs)
@util.async()
def kick_chat_member(self, *args):
return TeleBot.kick_chat_member(self, *args)
def kick_chat_member(self, *args, **kwargs):
return TeleBot.kick_chat_member(self, *args, **kwargs)
@util.async()
def unban_chat_member(self, *args):
return TeleBot.unban_chat_member(self, *args)
@util.async()
def restrict_chat_member(self, *args, **kwargs):
return TeleBot.restrict_chat_member(self, *args, **kwargs)
@util.async()
def promote_chat_member(self, *args, **kwargs):
return TeleBot.promote_chat_member(self, *args, **kwargs)
@util.async()
def export_chat_invite_link(self, *args):
return TeleBot.export_chat_invite_link(self, *args)
@util.async()
def set_chat_photo(self, *args):
return TeleBot.set_chat_photo(self, *args)
@util.async()
def delete_chat_photo(self, *args):
return TeleBot.delete_chat_photo(self, *args)
@util.async()
def set_chat_title(self, *args):
return TeleBot.set_chat_title(self, *args)
@util.async()
def set_chat_description(self, *args):
return TeleBot.set_chat_description(self, *args)
@util.async()
def pin_chat_message(self, *args, **kwargs):
return TeleBot.pin_chat_message(self, *args, **kwargs)
@util.async()
def unpin_chat_message(self, *args):
return TeleBot.unpin_chat_message(self, *args)
@util.async()
def edit_message_text(self, *args, **kwargs):
return TeleBot.edit_message_text(self, *args, **kwargs)
@ -1265,3 +1383,31 @@ class AsyncTeleBot(TeleBot):
@util.async()
def answer_callback_query(self, *args, **kwargs):
return TeleBot.answer_callback_query(self, *args, **kwargs)
@util.async()
def send_sticker(self, *args, **kwargs):
return TeleBot.send_sticker(self, *args, **kwargs)
@util.async()
def get_sticker_set(self, *args, **kwargs):
return TeleBot.get_sticker_set(self, *args, **kwargs)
@util.async()
def upload_sticker_file(self, *args, **kwargs):
return TeleBot.upload_sticker_file(self, *args, **kwargs)
@util.async()
def create_new_sticker_set(self, *args, **kwargs):
return TeleBot.create_new_sticker_set(self, *args, **kwargs)
@util.async()
def add_sticker_to_set(self, *args, **kwargs):
return TeleBot.add_sticker_to_set(self, *args, **kwargs)
@util.async()
def set_sticker_position_in_set(self, *args, **kwargs):
return TeleBot.set_sticker_position_in_set(self, *args, **kwargs)
@util.async()
def delete_sticker_from_set(self, *args, **kwargs):
return TeleBot.delete_sticker_from_set(self, *args, **kwargs)

View File

@ -18,7 +18,6 @@ from telebot import types
from telebot import util
logger = telebot.logger
req_session = requests.session()
proxy = None
API_URL = "https://api.telegram.org/bot{0}/{1}"
@ -28,6 +27,10 @@ CONNECT_TIMEOUT = 3.5
READ_TIMEOUT = 9999
def _get_req_session():
return util.per_thread('req_session', lambda: requests.session())
def _make_request(token, method_name, method='get', params=None, files=None, base_url=API_URL):
"""
Makes a request to the Telegram API.
@ -47,8 +50,8 @@ def _make_request(token, method_name, method='get', params=None, files=None, bas
if params:
if 'timeout' in params: read_timeout = params['timeout'] + 10
if 'connect-timeout' in params: connect_timeout = params['connect-timeout'] + 10
result = req_session.request(method, request_url, params=params, files=files,
timeout=(connect_timeout, read_timeout), proxies=proxy)
result = _get_req_session().request(method, request_url, params=params, files=files,
timeout=(connect_timeout, read_timeout), proxies=proxy)
logger.debug("The server returned: '{0}'".format(result.text.encode('utf8')))
return _check_result(method_name, result)['result']
@ -97,7 +100,7 @@ def get_file(token, file_id):
def download_file(token, file_path):
url = FILE_URL.format(token, file_path)
result = req_session.get(url)
result = _get_req_session().get(url)
if result.status_code != 200:
msg = 'The server returned HTTP {0} {1}. Response body:\n[{2}]' \
.format(result.status_code, result.reason, result.text)
@ -434,25 +437,46 @@ def unban_chat_member(token, chat_id, user_id):
return _make_request(token, method_url, params=payload, method='post')
def restrict_chat_member(token, chat_id, user_id, until_date=None, can_send_messages=True,
can_send_media_messages=True, can_send_other_messages=True,
can_add_web_page_previews=True):
def restrict_chat_member(token, chat_id, user_id, until_date=None, can_send_messages=None,
can_send_media_messages=None, can_send_other_messages=None,
can_add_web_page_previews=None):
method_url = 'restrictChatMember'
payload = {'chat_id': chat_id, 'user_id': user_id, 'until_date': until_date, 'can_send_messages': can_send_messages,
'can_send_media_messages': can_send_media_messages, 'can_send_other_messages': can_send_other_messages,
'can_add_web_page_previews': can_add_web_page_previews}
payload = {'chat_id': chat_id, 'user_id': user_id}
if until_date:
payload['until_date'] = until_date
if can_send_messages:
payload['can_send_messages'] = can_send_messages
if can_send_media_messages:
payload['can_send_media_messages'] = can_send_media_messages
if can_send_other_messages:
payload['can_send_other_messages'] = can_send_other_messages
if can_add_web_page_previews:
payload['can_add_web_page_previews'] = can_add_web_page_previews
return _make_request(token, method_url, params=payload, method='post')
def promote_chat_member(token, chat_id, user_id, can_change_info=False, can_post_messages=False,
can_edit_messages=False, can_delete_messages=False, can_invite_users=False,
can_restrict_members=False, can_pin_messages=False, can_promote_members=False):
def promote_chat_member(token, chat_id, user_id, can_change_info=None, can_post_messages=None,
can_edit_messages=None, can_delete_messages=None, can_invite_users=None,
can_restrict_members=None, can_pin_messages=None, can_promote_members=None):
method_url = 'promoteChatMember'
payload = {'chat_id': chat_id, 'user_id': user_id, 'can_change_info': can_change_info,
'can_post_messages': can_post_messages, 'can_edit_messages': can_edit_messages,
'can_delete_messages': can_delete_messages, 'can_invite_users': can_invite_users,
'can_restrict_members': can_restrict_members, 'can_pin_messages': can_pin_messages,
'can_promote_members': can_promote_members }
payload = {'chat_id': chat_id, 'user_id': user_id}
if can_change_info:
payload['can_change_info'] = can_change_info
if can_post_messages:
payload['can_post_messages'] = can_post_messages
if can_edit_messages:
payload['can_edit_messages'] = can_edit_messages
if can_delete_messages:
payload['can_delete_messages'] = can_delete_messages
if can_invite_users:
payload['can_invite_users'] = can_invite_users
if can_restrict_members:
payload['can_restrict_members'] = can_restrict_members
if can_pin_messages:
payload['can_pin_messages'] = can_pin_messages
if can_promote_members:
payload['can_promote_members'] = can_promote_members
return _make_request(token, method_url, params=payload, method='post')
@ -767,6 +791,58 @@ def answer_inline_query(token, inline_query_id, results, cache_time=None, is_per
return _make_request(token, method_url, params=payload, method='post')
def get_sticker_set(token, name):
method_url = 'getStickerSet'
return _make_request(token, method_url, params={'name': name})
def upload_sticker_file(token, user_id, png_sticker):
method_url = 'uploadStickerFile'
payload = {'user_id': user_id}
files = {'png_sticker': png_sticker}
return _make_request(token, method_url, params=payload, files=files, method='post')
def create_new_sticker_set(token, user_id, name, title, png_sticker, emojis, contains_masks=None, mask_position=None):
method_url = 'createNewStickerSet'
payload = {'user_id': user_id, 'name': name, 'title': title, 'emojis': emojis}
files = None
if not util.is_string(png_sticker):
files = {'png_sticker': png_sticker}
else:
payload['png_sticker'] = png_sticker
if contains_masks:
payload['contains_masks'] = contains_masks
if mask_position:
payload['mask_position'] = mask_position.to_json()
return _make_request(token, method_url, params=payload, files=files, method='post')
def add_sticker_to_set(token, user_id, name, png_sticker, emojis, mask_position):
method_url = 'addStickerToSet'
payload = {'user_id': user_id, 'name': name, 'emojis': emojis}
files = None
if not util.is_string(png_sticker):
files = {'png_sticker': png_sticker}
else:
payload['png_sticker'] = png_sticker
if mask_position:
payload['mask_position'] = mask_position.to_json()
return _make_request(token, method_url, params=payload, files=files, method='post')
def set_sticker_position_in_set(token, sticker, position):
method_url = 'setStickerPositionInSet'
payload = {'sticker': sticker, 'position': position}
return _make_request(token, method_url, params=payload, method='post')
def delete_sticker_from_set(token, sticker):
method_url = 'deleteStickerFromSet'
payload = {'sticker': sticker}
return _make_request(token, method_url, params=payload, method='post')
def _convert_list_json_serializable(results):
ret = ''
for r in results:

View File

@ -305,7 +305,11 @@ class Message(JsonDeserializable):
opts['new_chat_member'] = User.de_json(obj['new_chat_member'])
content_type = 'new_chat_member'
if 'new_chat_members' in obj:
opts['new_chat_members'] = obj['new_chat_members']
chat_members = obj['new_chat_members']
nms = []
for m in chat_members:
nms.append(User.de_json(m))
opts['new_chat_members'] = nms
content_type = 'new_chat_members'
if 'left_chat_member' in obj:
opts['left_chat_member'] = User.de_json(obj['left_chat_member'])
@ -382,6 +386,7 @@ class Message(JsonDeserializable):
self.location = None
self.venue = None
self.new_chat_member = None
self.new_chat_members = None
self.left_chat_member = None
self.new_chat_title = None
self.new_chat_photo = None
@ -897,8 +902,8 @@ class ChatMember(JsonDeserializable):
can_send_messages, can_send_media_messages, can_send_other_messages, can_add_web_page_previews)
def __init__(self, user, status, until_date, can_be_edited, can_change_info, can_post_messages, can_edit_messages,
can_delete_messages, can_invite_users, can_restrict_members, can_pin_messages, can_promote_members,
can_send_messages, can_send_media_messages, can_send_other_messages, can_add_web_page_previews):
can_delete_messages, can_invite_users, can_restrict_members, can_pin_messages, can_promote_members,
can_send_messages, can_send_media_messages, can_send_other_messages, can_add_web_page_previews):
self.user = user
self.status = status
self.until_date = until_date
@ -916,6 +921,7 @@ class ChatMember(JsonDeserializable):
self.can_send_other_messages = can_send_other_messages
self.can_add_web_page_previews = can_add_web_page_previews
# InlineQuery
class InlineQuery(JsonDeserializable):
@ -1854,3 +1860,77 @@ class PreCheckoutQuery(JsonDeserializable):
self.invoice_payload = invoice_payload
self.shipping_option_id = shipping_option_id
self.order_info = order_info
# Stickers
class StickerSet(JsonDeserializable):
@classmethod
def de_json(cls, json_string):
obj = cls.check_json(json_string)
name = obj['name']
title = obj['title']
contains_masks = obj['contains_masks']
stickers = []
for s in obj['stickers']:
stickers.append(Sticker.de_json(s))
return cls(name, title, contains_masks, stickers)
def __init__(self, name, title, contains_masks, stickers):
self.stickers = stickers
self.contains_masks = contains_masks
self.title = title
self.name = name
class Sticker(JsonDeserializable):
@classmethod
def de_json(cls, json_string):
obj = cls.check_json(json_string)
file_id = obj['file_id']
width = obj['width']
height = obj['height']
thumb = None
if 'thumb' in obj:
thumb = PhotoSize.de_json(obj['thumb'])
emoji = obj.get('emoji')
set_name = obj.get('set_name')
mask_position = None
if 'mask_position' in obj:
mask_position = MaskPosition.de_json(obj['mask_position'])
file_size = obj.get('file_size')
return cls(file_id, width, height, thumb, emoji, set_name, mask_position, file_size)
def __init__(self, file_id, width, height, thumb, emoji, set_name, mask_position, file_size):
self.file_id = file_id
self.width = width
self.height = height
self.thumb = thumb
self.emoji = emoji
self.set_name = set_name
self.mask_position = mask_position
self.file_size = file_size
class MaskPosition(JsonDeserializable, JsonSerializable):
@classmethod
def de_json(cls, json_string):
obj = cls.check_json(json_string)
point = obj['point']
x_shift = obj['x_shift']
y_shift = obj['y_shift']
scale = obj['scale']
return cls(point, x_shift, y_shift, scale)
def __init__(self, point, x_shift, y_shift, scale):
self.point = point
self.x_shift = x_shift
self.y_shift = y_shift
self.scale = scale
def to_json(self):
return json.dumps(self.to_dic())
def to_dic(self):
return {'point': self.point, 'x_shift': self.x_shift, 'y_shift': self.y_shift, 'scale': self.scale}

View File

@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
import threading
import traceback
import re
import sys
import six
@ -16,6 +17,9 @@ except ImportError:
from telebot import logger
thread_local = threading.local()
class WorkerThread(threading.Thread):
count = 0
@ -56,8 +60,8 @@ class WorkerThread(threading.Thread):
self.done_event.set()
except Queue.Empty:
pass
except:
logger.debug("Exception occurred")
except Exception as e:
logger.error(type(e).__name__ + " occurred, args=" + str(e.args) + "\n" + traceback.format_exc())
self.exc_info = sys.exc_info()
self.exception_event.set()
@ -241,3 +245,12 @@ def extract_arguments(text):
regexp = re.compile("\/\w*(@\w*)*\s*([\s\S]*)",re.IGNORECASE)
result = regexp.match(text)
return result.group(2) if is_command(text) else None
def per_thread(key, construct_value):
try:
return getattr(thread_local, key)
except AttributeError:
value = construct_value()
setattr(thread_local, key, value)
return value