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

Merge branch 'master' into patch-2

This commit is contained in:
Natanael Andrés Garrido 2019-09-23 10:25:18 -03:00 committed by GitHub
commit f8e7c0f819
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 142 additions and 23 deletions

View File

@ -26,6 +26,7 @@
* [Using web hooks](#using-web-hooks)
* [Logging](#logging)
* [Proxy](#proxy)
* [New in library](#new-in-library)
* [F.A.Q.](#faq)
* [Bot 2.0](#bot-20)
* [How can I distinguish a User and a GroupChat in message.chat?](#how-can-i-distinguish-a-user-and-a-groupchat-in-messagechat)
@ -510,6 +511,10 @@ apihelper.proxy = {'https':'socks5://userproxy:password@proxy_address:port'}
```
## New in library
06.06.2019 - Добавленна поддержка опросов (Poll). Добавлены функции send_poll, stop_poll
## F.A.Q.
### Bot 2.0
@ -524,16 +529,16 @@ Telegram Bot API support new type Chat for message.chat.
- Check the ```type``` attribute in ```Chat``` object:
-
```python
if message.chat.type == “private”:
if message.chat.type == "private":
# private chat message
if message.chat.type == “group”:
if message.chat.type == "group":
# group chat message
if message.chat.type == “supergroup”:
if message.chat.type == "supergroup":
# supergroup chat message
if message.chat.type == “channel”:
if message.chat.type == "channel":
# channel message
```
@ -576,18 +581,23 @@ Get help. Discuss. Chat.
* [EmaProject](https://github.com/halkliff/emaproject) by [*halkliff*](https://github.com/halkliff) - Ema - Eastern Media Assistant was made thinking on the ease-to-use feature. Coding here is simple, as much as is fast and powerful.
* [filmratingbot](http://t.me/filmratingbot)([source](https://github.com/jcolladosp/film-rating-bot)) by [*jcolladosp*](https://github.com/jcolladosp) - Telegram bot using the Python API that gets films rating from IMDb and metacritic
* [you2mp3bot](http://t.me/you2mp3bot)([link](https://storebot.me/bot/you2mp3bot)) - This bot can convert a Youtube video to Mp3. All you need is send the URL video.
* [areajugonesbot](http://t.me/areajugonesbot)([link](http://t.me/areajugonesbot)) - The areajugonesbot sends news published on the videogames blog Areajugones to Telegram.
* [Send2Kindlebot](http://t.me/Send2KindleBot) ([source](https://github.com/GabrielRF/Send2KindleBot)) by *GabrielRF* - Send to Kindle service.
* [RastreioBot](http://t.me/RastreioBot) ([source](https://github.com/GabrielRF/RastreioBot)) by *GabrielRF* - Bot used to track packages on the Brazilian Mail Service.
* [filex_bot](http://t.me/filex_bot)([link](https://github.com/victor141516/FileXbot-telegram))
* [Spbu4UBot](http://t.me/Spbu4UBot)([link](https://github.com/EeOneDown/spbu4u)) by *EeOneDown* - Bot with timetables for SPbU students.
* [SmartySBot](http://t.me/ZDU_bot)([link](https://github.com/0xVK/SmartySBot)) by *0xVK* - Telegram timetable bot, for Zhytomyr Ivan Franko State University students.
* [SmartySBot](http://t.me/ZDU_bot)([link](https://github.com/0xVK/SmartySBot)) by *0xVK* - Telegram timetable bot, for Zhytomyr Ivan Franko State University students.
* [yandex_music_bot](http://t.me/yandex_music_bot)- Downloads tracks/albums/public playlists from Yandex.Music streaming service for free.
* [LearnIt](https://t.me/LearnItbot)([link](https://github.com/tiagonapoli/LearnIt)) - A Telegram Bot created to help people to memorize other languages vocabulary.
* [MusicQuiz_bot](https://t.me/MusicQuiz_bot) by [Etoneja](https://github.com/Etoneja) - Listen to audiosamles and try to name the performer of the song.
* [Bot-Telegram-Shodan ](https://github.com/rubenleon/Bot-Telegram-Shodan) by [rubenleon](https://github.com/rubenleon)
* [MandangoBot](https://t.me/MandangoBot) by @Alvaricias - Bot for managing Marvel Strike Force alliances (only in spanish, atm).
* [ManjaroBot](https://t.me/ManjaroBot) by [@NeoRanger](https://github.com/neoranger) - Bot for Manjaro Linux Spanish group with a lot of info for Manjaro Newbies.
* [VigoBusTelegramBot](https://t.me/vigobusbot) ([GitHub](https://github.com/Pythoneiro/VigoBus-TelegramBot)) - Bot that provides buses coming to a certain stop and their remaining time for the city of Vigo (Galicia - Spain)
* [kaishnik-bot](https://t.me/kaishnik_bot) ([source](https://github.com/airatk/kaishnik-bot)) by *airatk* - bot which shows all the necessary information to KNTRU-KAI students.
* [Creation Date](https://t.me/creationdatebot) by @karipov - interpolates account creation dates based on telegram given IDs
* [m0xbot](https://t.me/m0xbot) by [kor0p](https://github.com/kor0p) - tic-tac-toe.
* [kboardbot](https://t.me/kboardbot) by [kor0p](https://github.com/kor0p) - inline switches keyboard layout (English, Hebrew, Ukrainian, Russian).
* [Robbie](https://t.me/romdeliverybot) ([source](https://github.com/FacuM/romdeliverybot_support)) by @FacuM - Support Telegram bot for developers and maintainers.
* [AsadovBot](https://t.me/asadov_bot) ([source])(https://github.com/desexcile/BotApi)) by @DesExcile - Сatalog of poems by Eduard Asadov.
Want to have your bot listed here? Send a Telegram message to @eternnoir or @pevdh.

View File

@ -9,8 +9,8 @@ bot = telebot.TeleBot(TELEGRAM_TOKEN)
def gen_markup():
markup = InlineKeyboardMarkup()
markup.row_width = 2
markup.add(InlineKeyboardButton("Yes", callback_data=f"cb_yes"),
InlineKeyboardButton("No", callback_data=f"cb_no"))
markup.add(InlineKeyboardButton("Yes", callback_data="cb_yes"),
InlineKeyboardButton("No", callback_data="cb_no"))
return markup
@bot.callback_query_handler(func=lambda call: True)

View File

@ -86,11 +86,13 @@ def echo_message(message):
# Remove webhook, it fails sometimes the set if there is a previous webhook
bot.remove_webhook()
#bot.remove_webhook()
# Set webhook
bot.set_webhook(url=WEBHOOK_URL_BASE + WEBHOOK_URL_PATH,
certificate=open(WEBHOOK_SSL_CERT, 'r'))
# Beacuse telegram bot api server will check webhook server is alive.
# Here we need set webhook after server started manually.
#bot.set_webhook(url=WEBHOOK_URL_BASE + WEBHOOK_URL_PATH,
# certificate=open(WEBHOOK_SSL_CERT, 'r'))
# Start server
httpd = HTTPServer((WEBHOOK_LISTEN, WEBHOOK_PORT),

View File

@ -113,6 +113,7 @@ class TeleBot:
getUserProfilePhotos
getUpdates
getFile
sendPoll
kickChatMember
unbanChatMember
restrictChatMember
@ -364,12 +365,12 @@ class TeleBot:
for listener in self.update_listener:
self._exec_task(listener, new_messages)
def infinity_polling(self, *args, **kwargs):
def infinity_polling(self, timeout=20, *args, **kwargs):
while not self.__stop_polling.is_set():
try:
self.polling(*args, **kwargs)
self.polling(timeout=timeout, *args, **kwargs)
except Exception as e:
time.sleep(5)
time.sleep(timeout)
pass
logger.info("Break infinity polling")
@ -1044,6 +1045,12 @@ class TeleBot:
disable_notification, reply_to_message_id, reply_markup, provider_data)
return types.Message.de_json(result)
def send_poll(self, chat_id, poll, disable_notifications=False, reply_to_message=None, reply_markup=None):
return types.Message.de_json(apihelper.send_poll(self.token, chat_id, poll.question, poll.options, disable_notifications, reply_to_message, reply_markup))
def stop_poll(self, chat_id, message_id):
return types.Poll.de_json(apihelper.stop_poll(self.token, chat_id, message_id))
def answer_shipping_query(self, shipping_query_id, ok, shipping_options=None, error_message=None):
return apihelper.answer_shipping_query(self.token, shipping_query_id, ok, shipping_options, error_message)
@ -1333,7 +1340,7 @@ class TeleBot:
bot.send_message(message.chat.id, 'Document received, sir!')
# Handle all other commands.
@bot.message_handler(func=lambda message: True, content_types=['audio', 'video', 'document', 'text', 'location', 'contact', 'sticker'])
@bot.message_handler(func=lambda message: True, content_types=['audio', 'photo', 'voice', 'video', 'document', 'text', 'location', 'contact', 'sticker'])
def default_command(message):
bot.send_message(message.chat.id, "This is the default command handler.")
@ -1750,3 +1757,11 @@ class AsyncTeleBot(TeleBot):
@util.async_dec()
def delete_sticker_from_set(self, *args, **kwargs):
return TeleBot.delete_sticker_from_set(self, *args, **kwargs)
@util.async_dec()
def send_poll(self, *args, **kwargs):
return TeleBot.send_poll(self, *args, **kwargs)
@util.async_dec()
def stop_poll(self, *args, **kwargs):
return TeleBot.stop_poll(self, *args, **kwargs)

View File

@ -619,7 +619,7 @@ def edit_message_text(token, text, chat_id=None, message_id=None, inline_message
payload['disable_web_page_preview'] = disable_web_page_preview
if reply_markup:
payload['reply_markup'] = _convert_markup(reply_markup)
return _make_request(token, method_url, params=payload)
return _make_request(token, method_url, params=payload, method='post')
def edit_message_caption(token, caption, chat_id=None, message_id=None, inline_message_id=None,
@ -636,7 +636,7 @@ def edit_message_caption(token, caption, chat_id=None, message_id=None, inline_m
payload['parse_mode'] = parse_mode
if reply_markup:
payload['reply_markup'] = _convert_markup(reply_markup)
return _make_request(token, method_url, params=payload)
return _make_request(token, method_url, params=payload, method='post')
def edit_message_media(token, media, chat_id=None, message_id=None, inline_message_id=None, reply_markup=None):
@ -665,13 +665,13 @@ def edit_message_reply_markup(token, chat_id=None, message_id=None, inline_messa
payload['inline_message_id'] = inline_message_id
if reply_markup:
payload['reply_markup'] = _convert_markup(reply_markup)
return _make_request(token, method_url, params=payload)
return _make_request(token, method_url, params=payload, method='post')
def delete_message(token, chat_id, message_id):
method_url = r'deleteMessage'
payload = {'chat_id': chat_id, 'message_id': message_id}
return _make_request(token, method_url, params=payload)
return _make_request(token, method_url, params=payload, method='post')
# Game
@ -814,7 +814,7 @@ def answer_shipping_query(token, shipping_query_id, ok, shipping_options=None, e
:param ok: Specify True if delivery to the specified address is possible and False if there are any problems (for example, if delivery to the specified address is not possible)
:param shipping_options: Required if ok is True. A JSON-serialized array of available shipping options.
:param error_message: Required if ok is False. Error message in human readable form that explains why it is impossible to complete the order (e.g. "Sorry, delivery to your desired address is unavailable'). Telegram will display this message to the user.
:return:
:return:
"""
method_url = 'answerShippingQuery'
payload = {'shipping_query_id': shipping_query_id, 'ok': ok}
@ -832,7 +832,7 @@ def answer_pre_checkout_query(token, pre_checkout_query_id, ok, error_message=No
:param pre_checkout_query_id: Unique identifier for the query to be answered
:param ok: Specify True if everything is alright (goods are available, etc.) and the bot is ready to proceed with the order. Use False if there are any problems.
:param error_message: Required if ok is False. Error message in human readable form that explains the reason for failure to proceed with the checkout (e.g. "Sorry, somebody just bought the last of our amazing black T-shirts while you were busy filling out your payment details. Please choose a different color or garment!"). Telegram will display this message to the user.
:return:
:return:
"""
method_url = 'answerPreCheckoutQuery'
payload = {'pre_checkout_query_id': pre_checkout_query_id, 'ok': ok}
@ -938,6 +938,26 @@ def delete_sticker_from_set(token, sticker):
return _make_request(token, method_url, params=payload, method='post')
def send_poll(token, chat_id, question, options, disable_notifications=False, reply_to_message_id=None, reply_markup=None):
method_url = r'sendPoll'
payload = {'chat_id': str(chat_id), 'question': question, 'options': _convert_list_json_serializable(options)}
if disable_notifications:
payload['disable_notification'] = disable_notifications
if reply_to_message_id:
payload['reply_to_message_id'] = reply_to_message_id
if reply_markup:
payload['reply_markup'] = _convert_markup(reply_markup)
return _make_request(token, method_url, params=payload)
def stop_poll(token, chat_id, message_id, reply_markup=None):
method_url = r'stopPoll'
payload = {'chat_id': str(chat_id), 'message_id': message_id}
if reply_markup:
payload['reply_markup'] = _convert_markup(reply_markup)
return _make_request(token, method_url, params=payload)
def _convert_list_json_serializable(results):
ret = ''
for r in results:

View File

@ -368,6 +368,9 @@ class Message(JsonDeserializable):
if 'connected_website' in obj:
opts['connected_website'] = obj['connected_website']
content_type = 'connected_website'
if 'poll' in obj:
opts['poll'] = Poll.de_json(obj['poll'])
content_type = 'poll'
return cls(message_id, from_user, date, chat, content_type, opts, json_string)
@classmethod
@ -885,9 +888,30 @@ class InlineKeyboardMarkup(Dictionaryable, JsonSerializable):
return json_dict
class LoginUrl(JsonSerializable):
def __init__(self, url, forward_text=None, bot_username=None, request_write_access=None):
self.url = url
self.forward_text = forward_text
self.bot_username = bot_username
self.request_write_access = request_write_access
def to_json(self):
return json.dumps(self.to_dic())
def to_dic(self):
json_dic = {'url': self.url}
if self.forward_text:
json_dic['forward_text'] = self.forward_text
if self.bot_username:
json_dic['bot_username'] = self.bot_username
if self.request_write_access:
json_dic['request_write_access'] = self.request_write_access
return json_dic
class InlineKeyboardButton(JsonSerializable):
def __init__(self, text, url=None, callback_data=None, switch_inline_query=None,
switch_inline_query_current_chat=None, callback_game=None, pay=None):
switch_inline_query_current_chat=None, callback_game=None, pay=None, login_url=None):
self.text = text
self.url = url
self.callback_data = callback_data
@ -895,6 +919,7 @@ class InlineKeyboardButton(JsonSerializable):
self.switch_inline_query_current_chat = switch_inline_query_current_chat
self.callback_game = callback_game
self.pay = pay
self.login_url = login_url
def to_json(self):
return json.dumps(self.to_dic())
@ -913,6 +938,8 @@ class InlineKeyboardButton(JsonSerializable):
json_dic['callback_game'] = self.callback_game
if self.pay is not None:
json_dic['pay'] = self.pay
if self.login_url is not None:
json_dic['login_url'] = self.login_url.to_dic()
return json_dic
@ -2173,3 +2200,48 @@ class InputMediaDocument(InputMedia):
if self.thumb:
ret['thumb'] = self.thumb
return ret
class PollOption(JsonSerializable, JsonDeserializable):
@classmethod
def de_json(cls, json_type):
obj = cls.check_json(json_type)
text = obj['text']
voter_count = int(obj['voter_count'])
option = cls(text)
option.voter_count = voter_count
return option
def __init__(self, text):
self.text = text
self.voter_count = 0
def to_json(self):
return json.dumps(self.text)
class Poll(JsonDeserializable):
@classmethod
def de_json(cls, json_type):
obj = cls.check_json(json_type)
poll_id = obj['id']
question = obj['question']
poll = cls(question)
options = []
for opt in obj['options']:
options.append(PollOption.de_json(opt))
poll.options = options
is_closed = obj['is_closed']
poll.id = poll_id
poll.is_closed = is_closed
return poll
def __init__(self, question):
self.options = []
self.question = question
def add(self, option):
if type(option) is PollOption:
self.options.append(option)
else:
self.options.append(PollOption(option))