diff --git a/aiogram/__init__.py b/aiogram/__init__.py index f7e61e76..77ceb357 100644 --- a/aiogram/__init__.py +++ b/aiogram/__init__.py @@ -38,5 +38,5 @@ __all__ = [ 'utils' ] -__version__ = '2.1.dev1' -__api_version__ = '4.1' +__version__ = '2.1.dev2' +__api_version__ = '4.2' diff --git a/aiogram/bot/base.py b/aiogram/bot/base.py index cab491d1..19031fd0 100644 --- a/aiogram/bot/base.py +++ b/aiogram/bot/base.py @@ -1,6 +1,7 @@ import asyncio import io import ssl +import typing from typing import Dict, List, Optional, Union import aiohttp @@ -17,12 +18,16 @@ class BaseBot: Base class for bot. It's raw bot. """ - def __init__(self, token: base.String, - loop: Optional[Union[asyncio.BaseEventLoop, asyncio.AbstractEventLoop]] = None, - connections_limit: Optional[base.Integer] = None, - proxy: Optional[base.String] = None, proxy_auth: Optional[aiohttp.BasicAuth] = None, - validate_token: Optional[base.Boolean] = True, - parse_mode=None): + def __init__( + self, + token: base.String, + loop: Optional[Union[asyncio.BaseEventLoop, asyncio.AbstractEventLoop]] = None, + connections_limit: Optional[base.Integer] = None, + proxy: Optional[base.String] = None, + proxy_auth: Optional[aiohttp.BasicAuth] = None, + validate_token: Optional[base.Boolean] = True, + parse_mode: typing.Optional[base.String] = None, + ): """ Instructions how to get Bot token is found here: https://core.telegram.org/bots#3-how-do-i-create-a-bot diff --git a/aiogram/bot/bot.py b/aiogram/bot/bot.py index 42caf989..0e13d62b 100644 --- a/aiogram/bot/bot.py +++ b/aiogram/bot/bot.py @@ -847,6 +847,43 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): result = await self.request(api.Methods.SEND_CONTACT, payload) return types.Message(**result) + async def send_poll(self, chat_id: typing.Union[base.Integer, base.String], + question: base.String, + options: typing.List[base.String], + disable_notification: typing.Optional[base.Boolean], + reply_to_message_id: typing.Union[base.Integer, None], + reply_markup: typing.Union[types.InlineKeyboardMarkup, + types.ReplyKeyboardMarkup, + types.ReplyKeyboardRemove, + types.ForceReply, None] = None) -> types.Message: + """ + Use this method to send a native poll. A native poll can't be sent to a private chat. + On success, the sent Message is returned. + + :param chat_id: Unique identifier for the target chat + or username of the target channel (in the format @channelusername). + A native poll can't be sent to a private chat. + :type chat_id: :obj:`typing.Union[base.Integer, base.String]` + :param question: Poll question, 1-255 characters + :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 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 + :type reply_to_message_id: :obj:`typing.Optional[Integer]` + :param reply_markup: Additional interface options + :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, + types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply, None]` + :return: On success, the sent Message is returned + :rtype: :obj:`types.Message` + """ + options = prepare_arg(options) + payload = generate_payload(**locals()) + + result = await self.request(api.Methods.SEND_POLL, payload) + return types.Message(**result) + async def send_chat_action(self, chat_id: typing.Union[base.Integer, base.String], action: base.String) -> base.Boolean: """ @@ -1524,6 +1561,27 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): return result return types.Message(**result) + async def stop_poll(self, chat_id: typing.Union[base.String, base.Integer], + message_id: base.Integer, + reply_markup: typing.Union[types.InlineKeyboardMarkup, None] = None) -> types.Poll: + """ + Use this method to stop a poll which was sent by the bot. + On success, the stopped Poll with the final results is returned. + + :param chat_id: Unique identifier for the target chat or username of the target channel + :type chat_id: :obj:`typing.Union[base.String, base.Integer]` + :param message_id: Identifier of the original message with the poll + :type message_id: :obj:`base.Integer` + :param reply_markup: A JSON-serialized object for a new message inline keyboard. + :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, None]` + :return: On success, the stopped Poll with the final results is returned. + :rtype: :obj:`types.Poll` + """ + payload = generate_payload(**locals()) + + result = await self.request(api.Methods.STOP_POLL, payload) + return types.Poll(**result) + async def delete_message(self, chat_id: typing.Union[base.Integer, base.String], message_id: base.Integer) -> base.Boolean: """ @@ -2056,20 +2114,3 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): result = await self.request(api.Methods.GET_GAME_HIGH_SCORES, payload) return [types.GameHighScore(**gamehighscore) for gamehighscore in result] - - async def send_poll(self, chat_id: typing.Union[base.Integer, base.String], - question: base.String, - options: typing.List[base.String], - reply_to_message_id: typing.Union[base.Integer, None]): - options = prepare_arg(options) - payload = generate_payload(**locals()) - - result = await self.request(api.Methods.SEND_POLL, payload) - return types.Message(**result) - - async def stop_poll(self, chat_id: typing.Union[base.String, base.Integer], - message_id: base.Integer) -> types.Poll: - payload = generate_payload(**locals()) - - result = await self.request(api.Methods.STOP_POLL, payload) - return types.Poll(**result) diff --git a/aiogram/types/__init__.py b/aiogram/types/__init__.py index 1dcd2c1f..e509ee74 100644 --- a/aiogram/types/__init__.py +++ b/aiogram/types/__init__.py @@ -43,7 +43,7 @@ from .passport_element_error import PassportElementError, PassportElementErrorDa PassportElementErrorSelfie from .passport_file import PassportFile from .photo_size import PhotoSize -from .poll import PollOptions, Poll +from .poll import PollOption, Poll from .pre_checkout_query import PreCheckoutQuery from .reply_keyboard import KeyboardButton, ReplyKeyboardMarkup, ReplyKeyboardRemove from .response_parameters import ResponseParameters @@ -144,7 +144,7 @@ __all__ = ( 'PassportFile', 'PhotoSize', 'Poll', - 'PollOptions', + 'PollOption', 'PreCheckoutQuery', 'ReplyKeyboardMarkup', 'ReplyKeyboardRemove', diff --git a/aiogram/types/poll.py b/aiogram/types/poll.py index e3f8caca..316bca2d 100644 --- a/aiogram/types/poll.py +++ b/aiogram/types/poll.py @@ -4,7 +4,7 @@ from . import base from . import fields -class PollOptions(base.TelegramObject): +class PollOption(base.TelegramObject): text: base.String = fields.Field() voter_count: base.Integer = fields.Field() @@ -12,5 +12,5 @@ class PollOptions(base.TelegramObject): class Poll(base.TelegramObject): id: base.String = fields.Field() question: base.String = fields.Field() - options: typing.List[PollOptions] = fields.ListField(base=PollOptions) + options: typing.List[PollOption] = fields.ListField(base=PollOption) is_closed: base.Boolean = fields.Field()