Merge remote-tracking branch 'origin/master' into dev

# Conflicts:
#	aiogram/bot/base.py
This commit is contained in:
Alex Root Junior 2017-07-22 19:23:48 +03:00
commit 07835b504c
16 changed files with 360 additions and 55 deletions

View file

@ -2,9 +2,9 @@ from .bot import Bot
major_version = 0 major_version = 0
minor_version = 2 minor_version = 3
build_type = 'b' build_type = ''
build_number = 1 build_number = ''
__version__ = f"{major_version}.{minor_version}{build_type}{build_number}" __version__ = f"{major_version}.{minor_version}{build_type}{build_number}"

View file

@ -4,6 +4,7 @@ import os
import aiohttp import aiohttp
from ..exceptions import ValidationError, TelegramAPIError from ..exceptions import ValidationError, TelegramAPIError
from ..utils import json
log = logging.getLogger('aiogram') log = logging.getLogger('aiogram')
@ -40,7 +41,7 @@ async def _check_result(method_name, response):
raise TelegramAPIError(f"The server returned HTTP {response.status}. Response body:\n[{body}]", raise TelegramAPIError(f"The server returned HTTP {response.status}. Response body:\n[{body}]",
method_name, response.status, body) method_name, response.status, body)
result_json = await response.json() result_json = await response.json(loads=json.loads)
if not result_json.get('ok'): if not result_json.get('ok'):
body = await response.text() body = await response.text()
@ -83,7 +84,7 @@ def _compose_data(params, files=None):
async def request(session, token, method, data=None, files=None): async def request(session, token, method, data=None, files=None):
log.debug(f"Make request: '{method}' with data: {data or {}} and files {files or {}}") log.debug(f"Make request: '{method}' with data: {data or {}} and files {files or {}}")
data = _compose_data(data, files) data = _compose_data(data, files)
url = API_URL.format(token=token, method=method) url = Methods.api_url(token=token, method=method)
async with session.post(url, data=data) as response: async with session.post(url, data=data) as response:
return await _check_result(method, response) return await _check_result(method, response)
@ -122,6 +123,15 @@ class Methods:
GET_CHAT_ADMINISTRATORS = 'getChatAdministrators' GET_CHAT_ADMINISTRATORS = 'getChatAdministrators'
GET_CHAT_MEMBERS_COUNT = 'getChatMembersCount' GET_CHAT_MEMBERS_COUNT = 'getChatMembersCount'
GET_CHAT_MEMBER = 'getChatMember' GET_CHAT_MEMBER = 'getChatMember'
RESTRICT_CHAT_MEMBER = 'restrictChatMember'
PROMOTE_CHAT_MEMBER = 'promoteChatMember'
EXPORT_CHAT_INVITE_LINK = 'exportChatInviteLink'
SET_CHAT_PHOTO = 'setChatPhoto'
DELETE_CHAT_PHOTO = 'deleteChatPhoto'
SET_CHAT_TITLE = 'setChatTitle'
SET_CHAT_DESCRIPTION = 'setChatDescription'
PIN_CHAT_MESSAGE = 'pinChatMessage'
UNPIN_CHAT_MESSAGE = 'unpinChatMessage'
ANSWER_CALLBACK_QUERY = 'answerCallbackQuery' ANSWER_CALLBACK_QUERY = 'answerCallbackQuery'
ANSWER_INLINE_QUERY = 'answerInlineQuery' ANSWER_INLINE_QUERY = 'answerInlineQuery'
EDIT_MESSAGE_TEXT = 'editMessageText' EDIT_MESSAGE_TEXT = 'editMessageText'
@ -134,3 +144,11 @@ class Methods:
SEND_GAME = 'sendGame' SEND_GAME = 'sendGame'
SET_GAME_SCORE = 'setGameScore' SET_GAME_SCORE = 'setGameScore'
GET_GAME_HIGH_SCORES = 'getGameHighScores' GET_GAME_HIGH_SCORES = 'getGameHighScores'
@staticmethod
def api_url(token, method):
return API_URL.format(token=token, method=method)
@staticmethod
def file_url(token, path):
return FILE_URL.format(token=token, path=path)

View file

@ -1,4 +1,6 @@
import json import datetime
from ..utils import json
import time
from .base import BaseBot from .base import BaseBot
from .. import types from .. import types
@ -505,7 +507,7 @@ class Bot(BaseBot):
file = await super(Bot, self).get_file(file_id) file = await super(Bot, self).get_file(file_id)
return self.prepare_object(types.File.de_json(file)) return self.prepare_object(types.File.de_json(file))
async def kick_chat_user(self, chat_id, user_id) -> bool: async def kick_chat_member(self, chat_id, user_id) -> bool:
""" """
Use this method to kick a user from a group or a supergroup. In the case of supergroups, Use this method to kick a user from a group or a supergroup. In the case of supergroups,
the user will not be able to return to the group on their own using invite links, etc., the user will not be able to return to the group on their own using invite links, etc.,
@ -515,7 +517,133 @@ class Bot(BaseBot):
:param user_id: int :param user_id: int
:return: bool :return: bool
""" """
return await super(Bot, self).kick_chat_user(chat_id, user_id) return await super(Bot, self).kick_chat_member(chat_id, user_id)
async def promote_chat_member(self, chat_id: int, user_id: int, can_change_info: bool, can_post_messages: bool,
can_edit_messages: bool, can_delete_messages: bool, can_invite_users: bool,
can_restrict_members: bool, can_pin_messages: bool,
can_promote_members: bool) -> bool:
"""
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.
Pass False for all boolean parameters to demote a user.
:param chat_id: int
:param user_id: int
:param can_change_info: bool
:param can_post_messages: bool
:param can_edit_messages: bool
:param can_delete_messages: bool
:param can_invite_users: bool
:param can_restrict_members: bool
:param can_pin_messages: bool
:param can_promote_members: bool
:return: bool
"""
return await super(Bot, self).promote_chat_member(chat_id, user_id, can_change_info, can_post_messages,
can_edit_messages, can_delete_messages, can_invite_users,
can_restrict_members, can_pin_messages, can_promote_members)
async def restrict_chat_member(self, chat_id: int, user_id: int, until_date: int, can_send_messages: bool,
can_send_media_messages: bool, can_send_other_messages: bool,
can_add_web_page_previews: bool) -> bool:
"""
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 the appropriate admin rights.
Pass True for all boolean parameters to lift restrictions from a user.
:param chat_id: int
:param user_id: int
:param until_date: int
:param can_send_messages: bool
:param can_send_media_messages: bool
:param can_send_other_messages: bool
:param can_add_web_page_previews: bool
:return: bool
"""
if isinstance(until_date, datetime.datetime):
until_date = int(time.mktime(until_date.timetuple()))
return await super(Bot, self).restrict_chat_member(chat_id, user_id, until_date, can_send_messages,
can_send_media_messages, can_send_other_messages,
can_add_web_page_previews)
async def export_chat_invite_link(self, chat_id: int) -> str:
"""
Use this method to export an invite link to 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.
:param chat_id: int
:return:
"""
return await super(Bot, self).export_chat_invite_link(chat_id)
async def set_chat_photo(self, chat_id: int, photo) -> bool:
"""
Use this method to set a new profile photo for the chat.
Photos can't be changed for private chats.
The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
:param chat_id: int
:param photo: file or str
:return: bool
"""
return await super(Bot, self).set_chat_photo(chat_id, photo)
async def delete_chat_photo(self, chat_id: int) -> bool:
"""
Use this method to delete a chat photo.
Photos can't be changed for private chats.
The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
:param chat_id: int
:return: bool
"""
return await super(Bot, self).delete_chat_photo(chat_id)
async def set_chat_title(self, chat_id: int, title: str) -> bool:
"""
Use this method to change the title of a chat.
Titles can't be changed for private chats.
The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
:param chat_id: int
:param title: str
:return: bool
"""
return await super(Bot, self).set_chat_title(chat_id, title)
async def set_chat_description(self, chat_id: int, description: str) -> bool:
"""
Use this method to change the description of 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.
:param chat_id: int
:param description: str
:return: bool
"""
return await super(Bot, self).set_chat_description(chat_id, description)
async def pin_chat_message(self, chat_id: int, message_id: int, disable_notification: bool = False) -> bool:
"""
Use this method to pin a message in a supergroup.
The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
:param chat_id: int
:param message_id: int
:param disable_notification: bool
:return: bool
"""
return await super(Bot, self).pin_chat_message(chat_id, message_id, disable_notification)
async def unpin_chat_message(self, chat_id: int) -> bool:
"""
Use this method to unpin a message in a supergroup chat.
The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
:param chat_id: int
:return: bool
"""
return await super(Bot, self).unpin_chat_message(chat_id)
async def unban_chat_member(self, chat_id, user_id) -> bool: async def unban_chat_member(self, chat_id, user_id) -> bool:
""" """

View file

@ -12,7 +12,7 @@ log = logging.getLogger(__name__)
class Dispatcher: class Dispatcher:
def __init__(self, bot, loop=None): def __init__(self, bot, loop=None):
self.bot: Bot = bot self.bot: 'Bot' = bot
if loop is None: if loop is None:
loop = self.bot.loop loop = self.bot.loop

View file

@ -3,6 +3,7 @@ from .audio import Audio
from .callback_query import CallbackQuery from .callback_query import CallbackQuery
from .chat import Chat, ChatType, ChatActions from .chat import Chat, ChatType, ChatActions
from .chat_member import ChatMember, ChatMemberStatus from .chat_member import ChatMember, ChatMemberStatus
from .chat_photo import ChatPhoto
from .chosen_inline_result import ChosenInlineResult from .chosen_inline_result import ChosenInlineResult
from .contact import Contact from .contact import Contact
from .document import Document from .document import Document
@ -54,6 +55,7 @@ __all__ = [
'ChatActions', 'ChatActions',
'ChatMember', 'ChatMember',
'ChatMemberStatus', 'ChatMemberStatus',
'ChatPhoto',
'ChatType', 'ChatType',
'ChosenInlineResult', 'ChosenInlineResult',
'Contact', 'Contact',

View file

@ -61,7 +61,7 @@ class Deserializable:
return result return result
@property @property
def bot(self): def bot(self) -> 'Bot':
""" """
Bot instance Bot instance
""" """

View file

@ -1,4 +1,5 @@
from .base import Deserializable from .base import Deserializable
from .chat_photo import ChatPhoto
class Chat(Deserializable): class Chat(Deserializable):
@ -8,7 +9,8 @@ class Chat(Deserializable):
https://core.telegram.org/bots/api#chat https://core.telegram.org/bots/api#chat
""" """
def __init__(self, id, type, title, username, first_name, last_name, all_members_are_administrators): def __init__(self, id, type, title, username, first_name, last_name, all_members_are_administrators, photo,
description, invite_link):
self.id: int = id self.id: int = id
self.type: str = type self.type: str = type
self.title: str = title self.title: str = title
@ -16,6 +18,9 @@ class Chat(Deserializable):
self.first_name: str = first_name self.first_name: str = first_name
self.last_name: str = last_name self.last_name: str = last_name
self.all_members_are_administrators: bool = all_members_are_administrators self.all_members_are_administrators: bool = all_members_are_administrators
self.photo: ChatPhoto = photo
self.description: str = description
self.invite_link: str = invite_link
@classmethod @classmethod
def de_json(cls, raw_data) -> 'Chat': def de_json(cls, raw_data) -> 'Chat':
@ -28,8 +33,12 @@ class Chat(Deserializable):
first_name: str = raw_data.get('first_name') first_name: str = raw_data.get('first_name')
last_name: str = raw_data.get('last_name') last_name: str = raw_data.get('last_name')
all_members_are_administrators: bool = raw_data.get('all_members_are_administrators', False) all_members_are_administrators: bool = raw_data.get('all_members_are_administrators', False)
photo = raw_data.get('photo')
description = raw_data.get('description')
invite_link = raw_data.get('invite_link')
return Chat(id, type, title, username, first_name, last_name, all_members_are_administrators) return Chat(id, type, title, username, first_name, last_name, all_members_are_administrators, photo,
description, invite_link)
@property @property
def full_name(self): def full_name(self):
@ -51,6 +60,39 @@ class Chat(Deserializable):
return self.full_name return self.full_name
return None return None
async def set_photo(self, photo):
return await self.bot.set_chat_photo(self.id, photo)
async def delete_photo(self):
return await self.bot.delete_chat_photo(self.id)
async def set_title(self, title):
return await self.bot.set_chat_title(self.id, title)
async def set_description(self, description):
return await self.bot.delete_chat_description(self.id, description)
async def pin_message(self, message_id: int, disable_notification: bool = False):
return await self.bot.pin_chat_message(self.id, message_id, disable_notification)
async def unpin_message(self):
return await self.bot.unpin_chat_message(self.id)
async def leave(self):
return await self.bot.leave_chat(self.id)
async def get_administrators(self):
return await self.bot.get_chat_administrators(self.id)
async def get_members_count(self):
return await self.bot.get_chat_members_count(self.id)
async def get_member(self, user_id):
return await self.bot.get_chat_member(self.id, user_id)
async def do(self, action):
return await self.bot.send_chat_action(self.id, action)
class ChatType: class ChatType:
""" """

View file

@ -1,3 +1,5 @@
import datetime
from .base import Deserializable from .base import Deserializable
from .user import User from .user import User
@ -8,10 +10,34 @@ class ChatMember(Deserializable):
https://core.telegram.org/bots/api#chatmember https://core.telegram.org/bots/api#chatmember
""" """
def __init__(self, user, status):
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
):
self.user: User = user self.user: User = user
self.status: str = status self.status: str = status
self.until_date: datetime.datetime = until_date
self.can_be_edited: bool = can_be_edited
self.can_change_info: bool = can_change_info
self.can_post_messages: bool = can_post_messages
self.can_edit_messages: bool = can_edit_messages
self.can_delete_messages: bool = can_delete_messages
self.can_invite_users: bool = can_invite_users
self.can_restrict_members: bool = can_restrict_members
self.can_pin_messages: bool = can_pin_messages
self.can_promote_members: bool = can_promote_members
self.can_send_messages: bool = can_send_messages
self.can_send_media_messages: bool = can_send_media_messages
self.can_send_other_messages: bool = can_send_other_messages
self.can_add_web_page_previews: bool = can_add_web_page_previews
@classmethod
def _parse_date(cls, unix_time):
return datetime.datetime.fromtimestamp(unix_time)
@classmethod @classmethod
def de_json(cls, raw_data): def de_json(cls, raw_data):
raw_data = cls.check_json(raw_data) raw_data = cls.check_json(raw_data)
@ -19,7 +45,26 @@ class ChatMember(Deserializable):
user = User.deserialize(raw_data.get('user')) user = User.deserialize(raw_data.get('user'))
status = raw_data.get('status') status = raw_data.get('status')
return ChatMember(user, status) until_date = cls._parse_date(raw_data.get('until_date'))
can_be_edited = raw_data.get('can_be_edited')
can_change_info = raw_data.get('can_change_info')
can_post_messages = raw_data.get('can_post_messages')
can_edit_messages = raw_data.get('can_edit_messages')
can_delete_messages = raw_data.get('can_delete_messages')
can_invite_users = raw_data.get('can_invite_users')
can_restrict_members = raw_data.get('can_restrict_members')
can_pin_messages = raw_data.get('can_pin_messages')
can_promote_members = raw_data.get('can_promote_members')
can_send_messages = raw_data.get('can_send_messages')
can_send_media_messages = raw_data.get('can_send_media_messages')
can_send_other_messages = raw_data.get('can_send_other_messages')
can_add_web_page_previews = raw_data.get('can_add_web_page_previews')
return ChatMember(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
)
class ChatMemberStatus: class ChatMemberStatus:

View file

@ -0,0 +1,22 @@
from .base import Deserializable
class ChatPhoto(Deserializable):
"""
This object represents a chat photo.
https://core.telegram.org/bots/api#chatphoto
"""
def __init__(self, small_file_id, big_file_id):
self.small_file_id: str = small_file_id
self.big_file_id: str = big_file_id
@classmethod
def de_json(cls, raw_data):
raw_data = cls.check_json(raw_data)
small_file_id = raw_data.get('small_file_id')
big_file_id = raw_data.get('big_file_id')
return ChatPhoto(small_file_id, big_file_id)

View file

@ -26,3 +26,6 @@ class File(Deserializable):
file_path = raw_data.get('file_path') file_path = raw_data.get('file_path')
return File(file_id, file_size, file_path) return File(file_id, file_size, file_path)
async def download(self, destination=None, timeout=30, chunk_size=65536, seek=True):
return await self.bot.download_file(self.file_path, destination, timeout, chunk_size, seek)

View file

@ -15,7 +15,7 @@ class InputMessageContent(Serializable):
""" """
def to_json(self): def to_json(self):
return {k: v.to_json() if hasattr(v, 'to_json') else v for k, v in self.__dict__.items() if return {k: v.to_json() if hasattr(v, 'to_json') else v for k, v in self.__dict__.items() if
not k.startswith('_')} v is not None and not k.startswith('_')}
class InlineQueryResult(InputMessageContent): class InlineQueryResult(InputMessageContent):
@ -74,10 +74,10 @@ class InlineQueryResultArticle(InlineQueryResult):
https://core.telegram.org/bots/api#inlinequeryresultarticle https://core.telegram.org/bots/api#inlinequeryresultarticle
""" """
def __init__(self, type: str, id: str, title: str, input_message_content: InputMessageContent, def __init__(self, id: str, title: str, input_message_content: InputMessageContent,
reply_markup: InlineKeyboardMarkup = None, url: str = None, hide_url: bool = None, reply_markup: InlineKeyboardMarkup = None, url: str = None, hide_url: bool = None,
description: str = None, thumb_url: str = None, thumb_width: int = None, thumb_height: int = None): description: str = None, thumb_url: str = None, thumb_width: int = None, thumb_height: int = None):
self.type: str = type self.type = 'article'
self.id: str = id self.id: str = id
self.title: str = title self.title: str = title
self.input_message_content: InputMessageContent = input_message_content self.input_message_content: InputMessageContent = input_message_content
@ -99,10 +99,10 @@ class InlineQueryResultPhoto(InlineQueryResult):
https://core.telegram.org/bots/api#inlinequeryresultphoto https://core.telegram.org/bots/api#inlinequeryresultphoto
""" """
def __init__(self, type: str, id: str, photo_url: str, thumb_url: str, photo_width: int = None, def __init__(self, id: str, photo_url: str, thumb_url: str, photo_width: int = None,
photo_height: int = None, title: str = None, description: str = None, caption: str = None, photo_height: int = None, title: str = None, description: str = None, caption: str = None,
reply_markup: InlineKeyboardMarkup = None, input_message_content: InputMessageContent = None): reply_markup: InlineKeyboardMarkup = None, input_message_content: InputMessageContent = None):
self.type: str = type self.type = 'photo'
self.id: str = id self.id: str = id
self.photo_url: str = photo_url self.photo_url: str = photo_url
self.thumb_url: str = thumb_url self.thumb_url: str = thumb_url
@ -126,10 +126,10 @@ class InlineQueryResultGif(InlineQueryResult):
https://core.telegram.org/bots/api#inlinequeryresultgif https://core.telegram.org/bots/api#inlinequeryresultgif
""" """
def __init__(self, type: str, id: str, gif_url: str, thumb_url: str, gif_width: int = None, gif_height: int = None, def __init__(self, id: str, gif_url: str, thumb_url: str, gif_width: int = None, gif_height: int = None,
gif_duration: int = None, title: str = None, caption: str = None, gif_duration: int = None, title: str = None, caption: str = None,
reply_markup: InlineKeyboardMarkup = None, input_message_content: InputMessageContent = None): reply_markup: InlineKeyboardMarkup = None, input_message_content: InputMessageContent = None):
self.type: str = type self.type = 'gif'
self.id: str = id self.id: str = id
self.gif_url: str = gif_url self.gif_url: str = gif_url
self.gif_width: int = gif_width self.gif_width: int = gif_width
@ -153,10 +153,10 @@ class InlineQueryResultMpeg4Gif(InlineQueryResult):
https://core.telegram.org/bots/api#inlinequeryresultmpeg4gif https://core.telegram.org/bots/api#inlinequeryresultmpeg4gif
""" """
def __init__(self, type: str, id: str, mpeg4_url: str, thumb_url: str, mpeg4_width: int = None, def __init__(self, id: str, mpeg4_url: str, thumb_url: str, mpeg4_width: int = None,
mpeg4_height: int = None, mpeg4_duration: int = None, title: str = None, caption: str = None, mpeg4_height: int = None, mpeg4_duration: int = None, title: str = None, caption: str = None,
reply_markup: InlineKeyboardMarkup = None, input_message_content: InputMessageContent = None): reply_markup: InlineKeyboardMarkup = None, input_message_content: InputMessageContent = None):
self.type: str = type self.type = 'mpeg4_gif'
self.id: str = id self.id: str = id
self.mpeg4_url: str = mpeg4_url self.mpeg4_url: str = mpeg4_url
self.mpeg4_width: int = mpeg4_width self.mpeg4_width: int = mpeg4_width
@ -178,11 +178,11 @@ class InlineQueryResultVideo(InlineQueryResult):
https://core.telegram.org/bots/api#inlinequeryresultvideo https://core.telegram.org/bots/api#inlinequeryresultvideo
""" """
def __init__(self, type: str, id: str, video_url: str, mime_type: str, thumb_url: str, title: str, def __init__(self, id: str, video_url: str, mime_type: str, thumb_url: str, title: str,
caption: str = None, video_width: int = None, video_height: int = None, video_duration: int = None, caption: str = None, video_width: int = None, video_height: int = None, video_duration: int = None,
description: str = None, reply_markup: InlineKeyboardMarkup = None, description: str = None, reply_markup: InlineKeyboardMarkup = None,
input_message_content: InputMessageContent = None): input_message_content: InputMessageContent = None):
self.type: str = type self.type = 'video'
self.id: str = id self.id: str = id
self.video_url: str = video_url self.video_url: str = video_url
self.mime_type: str = mime_type self.mime_type: str = mime_type
@ -204,10 +204,10 @@ class InlineQueryResultAudio(InlineQueryResult):
https://core.telegram.org/bots/api#inlinequeryresultaudio https://core.telegram.org/bots/api#inlinequeryresultaudio
""" """
def __init__(self, type: str, id: str, audio_url: str, title: str, caption: str = None, performer: str = None, def __init__(self, id: str, audio_url: str, title: str, caption: str = None, performer: str = None,
audio_duration: int = None, reply_markup: InlineKeyboardMarkup = None, audio_duration: int = None, reply_markup: InlineKeyboardMarkup = None,
input_message_content: InputMessageContent = None): input_message_content: InputMessageContent = None):
self.type: str = type self.type = 'audio'
self.id: str = id self.id: str = id
self.audio_url: str = audio_url self.audio_url: str = audio_url
self.title: str = title self.title: str = title
@ -229,9 +229,9 @@ class InlineQueryResultVoice(InlineQueryResult):
https://core.telegram.org/bots/api#inlinequeryresultvoice https://core.telegram.org/bots/api#inlinequeryresultvoice
""" """
def __init__(self, type: str, id: str, voice_url: str, title: str, caption: str = None, voice_duration: int = None, def __init__(self, id: str, voice_url: str, title: str, caption: str = None, voice_duration: int = None,
reply_markup: InlineKeyboardMarkup = None, input_message_content: InputMessageContent = None): reply_markup: InlineKeyboardMarkup = None, input_message_content: InputMessageContent = None):
self.type: str = type self.type = 'voice'
self.id: str = id self.id: str = id
self.voice_url: str = voice_url self.voice_url: str = voice_url
self.title: str = title self.title: str = title
@ -250,11 +250,11 @@ class InlineQueryResultDocument(InlineQueryResult):
https://core.telegram.org/bots/api#inlinequeryresultdocument https://core.telegram.org/bots/api#inlinequeryresultdocument
""" """
def __init__(self, type: str, id: str, title: str, document_url: str, mime_type: str, caption: str = None, def __init__(self, id: str, title: str, document_url: str, mime_type: str, caption: str = None,
description: str = None, reply_markup: InlineKeyboardMarkup = None, description: str = None, reply_markup: InlineKeyboardMarkup = None,
input_message_content: InputMessageContent = None, thumb_url: str = None, thumb_width: int = None, input_message_content: InputMessageContent = None, thumb_url: str = None, thumb_width: int = None,
thumb_height: int = None): thumb_height: int = None):
self.type: str = type self.type = 'document'
self.id: str = id self.id: str = id
self.title: str = title self.title: str = title
self.caption: str = caption self.caption: str = caption
@ -276,10 +276,10 @@ class InlineQueryResultLocation(InlineQueryResult):
https://core.telegram.org/bots/api#inlinequeryresultlocation https://core.telegram.org/bots/api#inlinequeryresultlocation
""" """
def __init__(self, type: str, id: str, latitude: float, longitude: float, title: str, def __init__(self, id: str, latitude: float, longitude: float, title: str,
reply_markup: InlineKeyboardMarkup = None, input_message_content: InputMessageContent = None, reply_markup: InlineKeyboardMarkup = None, input_message_content: InputMessageContent = None,
thumb_url: str = None, thumb_width: int = None, thumb_height: int = None): thumb_url: str = None, thumb_width: int = None, thumb_height: int = None):
self.type: str = type self.type = 'location'
self.id: str = id self.id: str = id
self.latitude: float = latitude self.latitude: float = latitude
self.longitude: float = longitude self.longitude: float = longitude
@ -299,11 +299,11 @@ class InlineQueryResultVenue(InlineQueryResult):
https://core.telegram.org/bots/api#inlinequeryresultvenue https://core.telegram.org/bots/api#inlinequeryresultvenue
""" """
def __init__(self, type: str, id: str, latitude: float, longitude: float, title: str, address: str, def __init__(self, id: str, latitude: float, longitude: float, title: str, address: str,
foursquare_id: str = None, reply_markup: InlineKeyboardMarkup = None, foursquare_id: str = None, reply_markup: InlineKeyboardMarkup = None,
input_message_content: InputMessageContent = None, thumb_url: str = None, thumb_width: int = None, input_message_content: InputMessageContent = None, thumb_url: str = None, thumb_width: int = None,
thumb_height: int = None): thumb_height: int = None):
self.type: str = type self.type = 'venue'
self.id: str = id self.id: str = id
self.latitude: float = latitude self.latitude: float = latitude
self.longitude: float = longitude self.longitude: float = longitude
@ -328,10 +328,10 @@ class InlineQueryResultContact(InlineQueryResult):
https://core.telegram.org/bots/api#inlinequeryresultcontact https://core.telegram.org/bots/api#inlinequeryresultcontact
""" """
def __init__(self, type: str, id: str, phone_number: str, first_name: str, last_name: str = None, def __init__(self, id: str, phone_number: str, first_name: str, last_name: str = None,
reply_markup: InlineKeyboardMarkup = None, input_message_content: InputMessageContent = None, reply_markup: InlineKeyboardMarkup = None, input_message_content: InputMessageContent = None,
thumb_url: str = None, thumb_width: int = None, thumb_height: int = None): thumb_url: str = None, thumb_width: int = None, thumb_height: int = None):
self.type: str = type self.type = 'contact'
self.id: str = id self.id: str = id
self.phone_number: str = phone_number self.phone_number: str = phone_number
self.first_name: str = first_name self.first_name: str = first_name
@ -349,8 +349,8 @@ class InlineQueryResultGame(InlineQueryResult):
https://core.telegram.org/bots/api#inlinequeryresultgame https://core.telegram.org/bots/api#inlinequeryresultgame
""" """
def __init__(self, type: str, id: str, game_short_name: str, reply_markup: InlineKeyboardMarkup = None): def __init__(self, id: str, game_short_name: str, reply_markup: InlineKeyboardMarkup = None):
self.type: str = type self.type = 'game'
self.id: str = id self.id: str = id
self.game_short_name: str = game_short_name self.game_short_name: str = game_short_name
self.reply_markup: InlineKeyboardMarkup = reply_markup self.reply_markup: InlineKeyboardMarkup = reply_markup
@ -367,10 +367,10 @@ class InlineQueryResultCachedPhoto(InlineQueryResult):
https://core.telegram.org/bots/api#inlinequeryresultcachedphoto https://core.telegram.org/bots/api#inlinequeryresultcachedphoto
""" """
def __init__(self, type: str, id: str, photo_file_id: str, title: str = None, description: str = None, def __init__(self, id: str, photo_file_id: str, title: str = None, description: str = None,
caption: str = None, reply_markup: InlineKeyboardMarkup = None, caption: str = None, reply_markup: InlineKeyboardMarkup = None,
input_message_content: InputMessageContent = None): input_message_content: InputMessageContent = None):
self.type: str = type self.type = 'photo'
self.id: str = id self.id: str = id
self.photo_file_id: str = photo_file_id self.photo_file_id: str = photo_file_id
self.title: str = title self.title: str = title
@ -391,9 +391,9 @@ class InlineQueryResultCachedGif(InlineQueryResult):
https://core.telegram.org/bots/api#inlinequeryresultcachedgif https://core.telegram.org/bots/api#inlinequeryresultcachedgif
""" """
def __init__(self, type: str, id: str, gif_file_id: str, title: str = None, caption: str = None, def __init__(self, id: str, gif_file_id: str, title: str = None, caption: str = None,
reply_markup: InlineKeyboardMarkup = None, input_message_content: InputMessageContent = None): reply_markup: InlineKeyboardMarkup = None, input_message_content: InputMessageContent = None):
self.type: str = type self.type = 'gif'
self.id: str = id self.id: str = id
self.gif_file_id: str = gif_file_id self.gif_file_id: str = gif_file_id
self.title: str = title self.title: str = title
@ -413,9 +413,9 @@ class InlineQueryResultCachedMpeg4Gif(InlineQueryResult):
https://core.telegram.org/bots/api#inlinequeryresultcachedmpeg4gif https://core.telegram.org/bots/api#inlinequeryresultcachedmpeg4gif
""" """
def __init__(self, type: str, id: str, mpeg4_file_id: str, title: str = None, caption: str = None, def __init__(self, id: str, mpeg4_file_id: str, title: str = None, caption: str = None,
reply_markup: InlineKeyboardMarkup = None, input_message_content: InputMessageContent = None): reply_markup: InlineKeyboardMarkup = None, input_message_content: InputMessageContent = None):
self.type: str = type self.type = 'mpeg4_gif'
self.id: str = id self.id: str = id
self.mpeg4_file_id: str = mpeg4_file_id self.mpeg4_file_id: str = mpeg4_file_id
self.title: str = title self.title: str = title
@ -435,9 +435,9 @@ class InlineQueryResultCachedSticker(InlineQueryResult):
https://core.telegram.org/bots/api#inlinequeryresultcachedsticker https://core.telegram.org/bots/api#inlinequeryresultcachedsticker
""" """
def __init__(self, type: str, id: str, sticker_file_id: str, reply_markup: InlineKeyboardMarkup = None, def __init__(self, id: str, sticker_file_id: str, reply_markup: InlineKeyboardMarkup = None,
input_message_content: InputMessageContent = None): input_message_content: InputMessageContent = None):
self.type: str = type self.type = 'sticker'
self.id: str = id self.id: str = id
self.sticker_file_id: str = sticker_file_id self.sticker_file_id: str = sticker_file_id
self.reply_markup: InlineKeyboardMarkup = reply_markup self.reply_markup: InlineKeyboardMarkup = reply_markup
@ -455,10 +455,10 @@ class InlineQueryResultCachedDocument(InlineQueryResult):
https://core.telegram.org/bots/api#inlinequeryresultcacheddocument https://core.telegram.org/bots/api#inlinequeryresultcacheddocument
""" """
def __init__(self, type: str, id: str, title: str, document_file_id: str, description: str = None, def __init__(self, id: str, title: str, document_file_id: str, description: str = None,
caption: str = None, reply_markup: InlineKeyboardMarkup = None, caption: str = None, reply_markup: InlineKeyboardMarkup = None,
input_message_content: InputMessageContent = None): input_message_content: InputMessageContent = None):
self.type: str = type self.type = 'document'
self.id: str = id self.id: str = id
self.title: str = title self.title: str = title
self.document_file_id: str = document_file_id self.document_file_id: str = document_file_id
@ -477,9 +477,9 @@ class InlineQueryResultCachedVideo(InlineQueryResult):
https://core.telegram.org/bots/api#inlinequeryresultcachedvideo https://core.telegram.org/bots/api#inlinequeryresultcachedvideo
""" """
def __init__(self, type: str, id: str, video_file_id: str, title: str, description: str = None, caption: str = None, def __init__(self, id: str, video_file_id: str, title: str, description: str = None, caption: str = None,
reply_markup: InlineKeyboardMarkup = None, input_message_content: InputMessageContent = None): reply_markup: InlineKeyboardMarkup = None, input_message_content: InputMessageContent = None):
self.type: str = type self.type = 'video'
self.id: str = id self.id: str = id
self.video_file_id: str = video_file_id self.video_file_id: str = video_file_id
self.title: str = title self.title: str = title
@ -500,9 +500,9 @@ class InlineQueryResultCachedVoice(InlineQueryResult):
https://core.telegram.org/bots/api#inlinequeryresultcachedvoice https://core.telegram.org/bots/api#inlinequeryresultcachedvoice
""" """
def __init__(self, type: str, id: str, voice_file_id: str, title: str, caption: str = None, def __init__(self, id: str, voice_file_id: str, title: str, caption: str = None,
reply_markup: InlineKeyboardMarkup = None, input_message_content: InputMessageContent = None): reply_markup: InlineKeyboardMarkup = None, input_message_content: InputMessageContent = None):
self.type: str = type self.type = 'voice'
self.id: str = id self.id: str = id
self.voice_file_id: str = voice_file_id self.voice_file_id: str = voice_file_id
self.title: str = title self.title: str = title
@ -521,9 +521,9 @@ class InlineQueryResultCachedAudio(InlineQueryResult):
https://core.telegram.org/bots/api#inlinequeryresultcachedaudio https://core.telegram.org/bots/api#inlinequeryresultcachedaudio
""" """
def __init__(self, type: str, id: str, audio_file_id: str, caption: str = None, def __init__(self, id: str, audio_file_id: str, caption: str = None,
reply_markup: InlineKeyboardMarkup = None, input_message_content: InputMessageContent = None): reply_markup: InlineKeyboardMarkup = None, input_message_content: InputMessageContent = None):
self.type: str = type self.type = 'audio'
self.id: str = id self.id: str = id
self.audio_file_id: str = audio_file_id self.audio_file_id: str = audio_file_id
self.caption: str = caption self.caption: str = caption

View file

@ -216,6 +216,9 @@ class Message(Deserializable):
return False return False
return True return True
async def pin(self, disable_notification: bool = False):
return await self.chat.pin_message(self.message_id, disable_notification)
class ContentType: class ContentType:
""" """

View file

@ -69,3 +69,6 @@ class User(Deserializable):
if not hasattr(self, '_locale'): if not hasattr(self, '_locale'):
setattr(self, '_locale', babel.core.Locale.parse(self.language_code, sep='-')) setattr(self, '_locale', babel.core.Locale.parse(self.language_code, sep='-'))
return getattr(self, '_locale') return getattr(self, '_locale')
async def get_user_profile_photos(self, offset=None, limit=None):
return await self.bot.get_user_profile_photos(self.id, offset, limit)

12
aiogram/utils/json.py Normal file
View file

@ -0,0 +1,12 @@
try:
import ujson as json
except ImportError:
import json
def dumps(data):
return json.dumps(data)
def loads(data):
return json.loads(data)

26
examples/inline_bot.py Normal file
View file

@ -0,0 +1,26 @@
import asyncio
import logging
from aiogram import Bot, types
from aiogram.dispatcher import Dispatcher
API_TOKEN = 'BOT TOKEN HERE'
logging.basicConfig(level=logging.DEBUG)
loop = asyncio.get_event_loop()
bot = Bot(token=API_TOKEN, loop=loop)
dp = Dispatcher(bot)
@dp.inline_handler()
async def inline_echo(inline_query: types.InlineQuery):
item = types.InlineQueryResultArticle('1', 'echo', types.InputTextMessageContent(inline_query.query))
await bot.answer_inline_query(inline_query.id, results=[item], cache_time=1)
if __name__ == '__main__':
try:
loop.run_until_complete(dp.start_pooling())
except KeyboardInterrupt:
loop.stop()

View file

@ -1,3 +1,4 @@
ujson
aiohttp>=2.1.0 aiohttp>=2.1.0
appdirs>=1.4.3 appdirs>=1.4.3
async-timeout>=1.2.1 async-timeout>=1.2.1