Bot API 4.6

This commit is contained in:
gabbhack 2020-01-23 20:23:08 +05:00
parent 7afe783914
commit ee803303aa
7 changed files with 141 additions and 2 deletions

View file

@ -863,6 +863,11 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin):
async def send_poll(self, chat_id: typing.Union[base.Integer, base.String],
question: base.String,
options: typing.List[base.String],
is_anonymous: typing.Optional[base.Boolean] = None,
type: typing.Optional[base.String] = None,
allows_multiple_answers: typing.Optional[base.Boolean] = None,
correct_option_id: typing.Optional[base.Integer] = None,
is_closed: typing.Optional[base.Boolean] = None,
disable_notification: typing.Optional[base.Boolean] = None,
reply_to_message_id: typing.Optional[base.Integer] = None,
reply_markup: typing.Union[types.InlineKeyboardMarkup,
@ -881,6 +886,16 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin):
:type question: :obj:`base.String`
:param options: List of answer options, 2-10 strings 1-100 characters each
:param options: :obj:`typing.List[base.String]`
:param is_anonymous: True, if the poll needs to be anonymous, defaults to True
:param is_anonymous: :obj:`typing.Optional[base.Boolean]`
:param type: Poll type, quiz or regular, defaults to regular
:param type: :obj:`typing.Optional[base.String]`
:param allows_multiple_answers: True, if the poll allows multiple answers, ignored for polls in quiz mode, defaults to False
:param allows_multiple_answers: :obj:`typing.Optional[base.Boolean]`
:param correct_option_id: 0-based identifier of the correct answer option, required for polls in quiz mode
:param correct_option_id: :obj:`typing.Optional[base.Integer]`
:param is_closed: Pass True, if the poll needs to be immediately closed
:param is_closed: :obj:`typing.Optional[base.Boolean]`
:param disable_notification: Sends the message silently. Users will receive a notification with no sound.
:type disable_notification: :obj:`typing.Optional[Boolean]`
:param reply_to_message_id: If the message is a reply, ID of the original message

View file

@ -69,6 +69,7 @@ class Dispatcher(DataMixin, ContextInstanceMixin):
self.shipping_query_handlers = Handler(self, middleware_key='shipping_query')
self.pre_checkout_query_handlers = Handler(self, middleware_key='pre_checkout_query')
self.poll_handlers = Handler(self, middleware_key='poll')
self.poll_answer_handlers = Handler(self, middleware_key='poll_answer')
self.errors_handlers = Handler(self, once=False, middleware_key='error')
self.middleware = MiddlewareManager(self)
@ -87,6 +88,7 @@ class Dispatcher(DataMixin, ContextInstanceMixin):
filters_factory.bind(StateFilter, exclude_event_handlers=[
self.errors_handlers,
self.poll_handlers,
self.poll_answer_handlers,
])
filters_factory.bind(ContentTypeFilter, event_handlers=[
self.message_handlers,
@ -226,6 +228,8 @@ class Dispatcher(DataMixin, ContextInstanceMixin):
return await self.pre_checkout_query_handlers.notify(update.pre_checkout_query)
if update.poll:
return await self.poll_handlers.notify(update.poll)
if update.poll_answer:
return await self.poll_answer_handlers.notify(update.poll_answer)
except Exception as e:
err = await self.errors_handlers.notify(update, e)
if err:
@ -853,18 +857,90 @@ class Dispatcher(DataMixin, ContextInstanceMixin):
return decorator
def register_poll_handler(self, callback, *custom_filters, run_task=None, **kwargs):
"""
Register handler for poll
Example:
.. code-block:: python3
dp.register_poll_handler(some_poll_handler)
:param callback:
:param custom_filters:
:param run_task: run callback in task (no wait results)
:param kwargs:
"""
filters_set = self.filters_factory.resolve(self.poll_handlers,
*custom_filters,
**kwargs)
self.poll_handlers.register(self._wrap_async_task(callback, run_task), filters_set)
def poll_handler(self, *custom_filters, run_task=None, **kwargs):
"""
Decorator for poll handler
Example:
.. code-block:: python3
@dp.poll_handler()
async def some_poll_handler(poll: types.Poll)
:param custom_filters:
:param run_task: run callback in task (no wait results)
:param kwargs:
"""
def decorator(callback):
self.register_poll_handler(callback, *custom_filters, run_task=run_task,
**kwargs)
return callback
return decorator
def register_poll_answer_handler(self, callback, *custom_filters, run_task=None, **kwargs):
"""
Register handler for poll_answer
Example:
.. code-block:: python3
dp.register_poll_answer_handler(some_poll_answer_handler)
:param callback:
:param custom_filters:
:param run_task: run callback in task (no wait results)
:param kwargs:
"""
filters_set = self.filters_factory.resolve(self.poll_answer_handlers,
*custom_filters,
**kwargs)
self.poll_handlers.register(self._wrap_async_task(callback, run_task), filters_set)
def poll_answer_handler(self, *custom_filters, run_task=None, **kwargs):
"""
Decorator for poll_answer handler
Example:
.. code-block:: python3
@dp.poll_answer_handler()
async def some_poll_answer_handler(poll: types.Poll)
:param custom_filters:
:param run_task: run callback in task (no wait results)
:param kwargs:
"""
def decorator(callback):
self.register_poll_answer_handler(callback, *custom_filters, run_task=run_task,
**kwargs)
return callback
return decorator
def register_errors_handler(self, callback, *custom_filters, exception=None, run_task=None, **kwargs):
"""

View file

@ -18,6 +18,7 @@ class MessageEntity(base.TelegramObject):
length: base.Integer = fields.Field()
url: base.String = fields.Field()
user: User = fields.Field(base=User)
langugage: base.String = fields.Field()
def get_text(self, text):
"""

View file

@ -2,15 +2,42 @@ import typing
from . import base
from . import fields
from .user import User
class PollOption(base.TelegramObject):
"""
This object contains information about one answer option in a poll.
https://core.telegram.org/bots/api#polloption
"""
text: base.String = fields.Field()
voter_count: base.Integer = fields.Field()
class PollAnswer(base.TelegramObject):
"""
This object represents an answer of a user in a non-anonymous poll.
https://core.telegram.org/bots/api#pollanswer
"""
poll_id: base.String = fields.Field()
user: User = fields.Field()
option_ids: typing.List[base.Integer] = fields.ListField()
class Poll(base.TelegramObject):
"""
This object contains information about a poll.
https://core.telegram.org/bots/api#poll
"""
id: base.String = fields.Field()
question: base.String = fields.Field()
options: typing.List[PollOption] = fields.ListField(base=PollOption)
total_voter_count: base.Integer = fields.Field()
is_closed: base.Boolean = fields.Field()
is_anonymous: base.Boolean = fields.Field()
poll_type: base.String = fields.Field(alias="type")
allows_multiple_answers: base.Boolean = fields.Field()
correct_option_id: base.Integer = fields.Field()

View file

@ -4,6 +4,18 @@ from . import base
from . import fields
class KeyboardButtonPollType(base.TelegramObject):
"""
This object represents type of a poll, which is allowed to be created and sent when the corresponding button is pressed.
https://core.telegram.org/bots/api#keyboardbuttonpolltype
"""
poll_type: base.String = fields.Field(alias="type")
def __init__(self, poll_type: base.String):
super(KeyboardButtonPollType, self).__init__(poll_type=poll_type)
class ReplyKeyboardMarkup(base.TelegramObject):
"""
This object represents a custom keyboard with reply options (see Introduction to bots for details and examples).
@ -81,14 +93,16 @@ class ReplyKeyboardMarkup(base.TelegramObject):
class KeyboardButton(base.TelegramObject):
"""
This object represents one button of the reply keyboard. For simple text buttons String can be used instead of this object to specify text of the button. Optional fields are mutually exclusive.
This object represents one button of the reply keyboard. For simple text buttons String can be used instead of this object to specify text of the button. Optional fields request_contact, request_location, and request_poll are mutually exclusive.
Note: request_contact and request_location options will only work in Telegram versions released after 9 April, 2016. Older clients will ignore them.
Note: request_poll option will only work in Telegram versions released after 23 January, 2020. Older clients will receive unsupported message.
https://core.telegram.org/bots/api#keyboardbutton
"""
text: base.String = fields.Field()
request_contact: base.Boolean = fields.Field()
request_location: base.Boolean = fields.Field()
request_poll: KeyboardButtonPollType = fields.Field()
def __init__(self, text: base.String,
request_contact: base.Boolean = None,

View file

@ -6,7 +6,7 @@ from .callback_query import CallbackQuery
from .chosen_inline_result import ChosenInlineResult
from .inline_query import InlineQuery
from .message import Message
from .poll import Poll
from .poll import Poll, PollAnswer
from .pre_checkout_query import PreCheckoutQuery
from .shipping_query import ShippingQuery
from ..utils import helper
@ -30,6 +30,7 @@ class Update(base.TelegramObject):
shipping_query: ShippingQuery = fields.Field(base=ShippingQuery)
pre_checkout_query: PreCheckoutQuery = fields.Field(base=PreCheckoutQuery)
poll: Poll = fields.Field(base=Poll)
poll_answer: PollAnswer = fields.Field(base=PollAnswer)
def __hash__(self):
return self.update_id
@ -58,3 +59,5 @@ class AllowedUpdates(helper.Helper):
CALLBACK_QUERY = helper.ListItem() # callback_query
SHIPPING_QUERY = helper.ListItem() # shipping_query
PRE_CHECKOUT_QUERY = helper.ListItem() # pre_checkout_query
POLL = helper.ListItem() # poll
POLL_ANSWER = helper.ListItem() # poll_answer

View file

@ -22,6 +22,9 @@ class User(base.TelegramObject):
last_name: base.String = fields.Field()
username: base.String = fields.Field()
language_code: base.String = fields.Field()
can_join_groups: base.Boolean = fields.Field()
can_read_all_group_messages: base.Boolean = fields.Field()
supports_inline_queries: base.Boolean = fields.Field()
@property
def full_name(self):