2017-05-19 21:20:59 +03:00
import asyncio
2017-05-26 08:58:07 +03:00
import json
2017-05-19 21:20:59 +03:00
import aiohttp
2017-06-02 01:34:27 +03:00
from aiogram . types . chat_member import ChatMember
2017-05-30 23:22:20 +03:00
from aiogram . types . file import File
2017-05-30 23:18:47 +03:00
from aiogram . types . user_profile_photos import UserProfilePhotos
2017-05-30 23:31:59 +03:00
from aiogram . types . webhook_info import WebhookInfo
2017-05-19 21:20:59 +03:00
from . import api
from . api import ApiMethods
2017-05-19 22:11:27 +03:00
from . types . chat import Chat
2017-05-26 07:55:05 +03:00
from . types . message import Message
2017-05-20 00:00:45 +03:00
from . types . update import Update
2017-05-19 21:20:59 +03:00
from . types . user import User
2017-05-21 22:51:48 +03:00
from . utils . payload import generate_payload
2017-05-19 21:20:59 +03:00
class AIOGramBot :
def __init__ ( self , token , loop = None , connections_limit = 10 ) :
"""
: param token :
: param loop :
: param connections_limit :
"""
self . __token = token
if loop is None :
loop = asyncio . get_event_loop ( )
self . loop = loop
self . session = aiohttp . ClientSession (
connector = aiohttp . TCPConnector ( limit = connections_limit ) ,
loop = self . loop )
2017-05-27 03:09:59 +03:00
api . check_token ( token )
2017-05-21 22:51:48 +03:00
def __del__ ( self ) :
2017-05-27 03:09:59 +03:00
if self . session and not self . session . closed :
self . session . close ( )
2017-05-19 21:20:59 +03:00
2017-05-30 21:42:12 +03:00
def prepare_object ( self , obj , parent = None ) :
2017-05-26 05:17:26 +03:00
obj . bot = self
2017-05-30 21:42:12 +03:00
obj . parent = parent
2017-05-26 05:17:26 +03:00
return obj
2017-05-19 21:20:59 +03:00
@property
async def me ( self ) - > User :
if not hasattr ( self , ' _me ' ) :
setattr ( self , ' _me ' , await self . get_me ( ) )
return getattr ( self , ' _me ' )
2017-05-26 09:42:19 +03:00
async def request ( self , method , data = None , files = None ) :
return await api . request ( self . session , self . __token , method , data , files )
2017-05-19 21:59:08 +03:00
2017-05-30 23:09:17 +03:00
async def _send_file ( self , file_type , file , payload ) :
methods = {
' photo ' : ApiMethods . SEND_PHOTO ,
' audio ' : ApiMethods . SEND_AUDIO ,
' document ' : ApiMethods . SEND_DOCUMENT ,
' sticker ' : ApiMethods . SEND_STICKER ,
' video ' : ApiMethods . SEND_VIDEO ,
' voice ' : ApiMethods . SEND_VOICE ,
' video_note ' : ApiMethods . SEND_VIDEO_NOTE
}
method = methods [ file_type ]
if isinstance ( file , str ) :
payload [ method ] = file
req = self . request ( method , payload )
else :
data = { file_type : file }
req = self . request ( ApiMethods . SEND_PHOTO , payload , data )
return self . prepare_object ( Message . de_json ( await req ) )
2017-05-19 21:20:59 +03:00
async def get_me ( self ) - > User :
2017-05-19 21:59:08 +03:00
raw = await self . request ( ApiMethods . GET_ME )
2017-05-26 05:17:26 +03:00
return self . prepare_object ( User . de_json ( raw ) )
2017-05-19 22:11:27 +03:00
2017-05-20 00:00:45 +03:00
async def get_updates ( self , offset = None , limit = None , timeout = None , allowed_updates = None ) :
"""
offset Integer Optional Identifier of the first update to be returned . Must be greater by one than the highest among the identifiers of previously received updates . By default , updates starting with the earliest unconfirmed update are returned . An update is considered confirmed as soon as getUpdates is called with an offset higher than its update_id . The negative offset can be specified to retrieve updates starting from - offset update from the end of the updates queue . All previous updates will forgotten .
limit Integer Optional Limits the number of updates to be retrieved . Values between 1 — 100 are accepted . Defaults to 100.
timeout Integer Optional Timeout in seconds for long polling . Defaults to 0 , i . e . usual short polling . Should be positive , short polling should be used for testing purposes only .
allowed_updates Array of String Optional List the types of updates you want your bot to receive . For example , specify [ “ message ” , “ edited_channel_post ” , “ callback_query ” ] to only receive updates of these types . See Update for a complete list of available update types . Specify an empty list to receive all updates regardless of type ( default ) . If not specified , the previous setting will be used .
Please note that this parameter doesn ' t affect updates created before the call to the getUpdates, so unwanted updates may be received for a short period of time.
: return :
"""
2017-05-21 19:09:18 +03:00
payload = generate_payload ( * * locals ( ) )
2017-05-20 00:00:45 +03:00
raw = await self . request ( ApiMethods . GET_UPDATES , payload )
2017-05-26 05:17:26 +03:00
return [ self . prepare_object ( Update . de_json ( raw_update ) ) for raw_update in raw ]
2017-05-26 05:44:44 +03:00
2017-05-30 23:31:59 +03:00
async def set_webhook ( self , url , certificate = None , max_connections = None , allowed_updates = None ) :
payload = generate_payload ( * * locals ( ) , exclude = ' certificate ' )
if certificate :
cert = { ' certificate ' : certificate }
req = self . request ( ApiMethods . SET_WEBHOOK , payload , cert )
else :
req = self . request ( ApiMethods . SET_WEBHOOK , payload )
return self . prepare_object ( WebhookInfo . de_json ( await req ) )
async def delete_webhook ( self ) :
payload = { }
await self . request ( ApiMethods . DELETE_WEBHOOK , payload )
return True
async def get_webhook_info ( self ) :
payload = { }
webhook_info = await self . request ( ApiMethods . GET_WEBHOOK_INFO , payload )
return self . prepare_object ( webhook_info )
2017-05-26 05:44:44 +03:00
async def send_message ( self , chat_id , text , parse_mode = None , disable_web_page_preview = None ,
disable_notification = None , reply_to_message_id = None , reply_markup = None ) :
"""
chat_id Integer or String Yes Unique identifier for the target chat or username of the target channel ( in the format @channelusername )
text String Yes Text of the message to be sent
parse_mode String Optional Send Markdown or HTML , if you want Telegram apps to show bold , italic , fixed - width text or inline URLs in your bot ' s message.
disable_web_page_preview Boolean Optional Disables link previews for links in this message
disable_notification Boolean Optional Sends the message silently . iOS users will not receive a notification , Android users will receive a notification with no sound .
reply_to_message_id Integer Optional If the message is a reply , ID of the original message
reply_markup InlineKeyboardMarkup or ReplyKeyboardMarkup or ReplyKeyboardRemove or ForceReply Optional Additional interface options . A JSON - serialized object for an inline keyboard , custom reply keyboard , instructions to remove reply keyboard or to force a reply from the user .
: return :
"""
2017-05-26 08:58:07 +03:00
if reply_markup and hasattr ( reply_markup , ' to_json ' ) :
reply_markup = json . dumps ( reply_markup . to_json ( ) )
2017-05-26 05:44:44 +03:00
2017-05-26 08:58:07 +03:00
if hasattr ( reply_to_message_id , ' message_id ' ) :
reply_to_message_id = reply_to_message_id . message_id
2017-05-26 05:44:44 +03:00
2017-05-26 08:58:07 +03:00
payload = generate_payload ( * * locals ( ) )
2017-05-26 05:44:44 +03:00
message = await self . request ( ApiMethods . SEND_MESSAGE , payload )
return self . prepare_object ( Message . de_json ( message ) )
async def delete_message ( self , chat_id , message_id ) :
payload = generate_payload ( * * locals ( ) )
2017-05-26 06:03:21 +03:00
await self . request ( ApiMethods . DELETE_MESSAGE , payload )
return True
async def forward_message ( self , chat_id , from_chat_id , message_id , disable_notification = None ) :
"""
chat_id Integer or String Yes Unique identifier for the target chat or username of the target channel ( in the format @channelusername )
from_chat_id Integer or String Yes Unique identifier for the chat where the original message was sent ( or channel username in the format @channelusername )
disable_notification Boolean Optional Sends the message silently . iOS users will not receive a notification , Android users will receive a notification with no sound .
message_id Integer Yes Message identifier in the chat specified in from_chat_id
: return :
"""
payload = generate_payload ( * * locals ( ) )
message = await self . request ( ApiMethods . FORWARD_MESSAGE , payload )
return self . prepare_object ( Message . de_json ( message ) )
2017-05-26 09:42:19 +03:00
async def send_photo ( self , chat_id , photo , caption = None , disable_notification = None , reply_to_message_id = None ,
reply_markup = None ) - > Message :
2017-05-30 22:57:20 +03:00
_message_type = ' photo '
2017-05-26 09:42:19 +03:00
if reply_markup and hasattr ( reply_markup , ' to_json ' ) :
reply_markup = json . dumps ( reply_markup . to_json ( ) )
if hasattr ( reply_to_message_id , ' message_id ' ) :
reply_to_message_id = reply_to_message_id . message_id
2017-05-30 22:57:20 +03:00
payload = generate_payload ( * * locals ( ) , exclude = [ _message_type ] )
return await self . _send_file ( _message_type , photo , payload )
2017-05-30 22:43:05 +03:00
async def send_audio ( self , chat_id , audio , caption = None , duration = None , performer = None , title = None ,
2017-05-30 22:46:14 +03:00
disable_notification = None , reply_to_message_id = None , reply_markup = None ) - > Message :
2017-05-30 22:57:20 +03:00
_message_type = ' audio '
2017-05-30 22:43:05 +03:00
if reply_markup and hasattr ( reply_markup , ' to_json ' ) :
reply_markup = json . dumps ( reply_markup . to_json ( ) )
if hasattr ( reply_to_message_id , ' message_id ' ) :
reply_to_message_id = reply_to_message_id . message_id
2017-05-30 22:57:20 +03:00
payload = generate_payload ( * * locals ( ) , exclude = [ _message_type ] )
return await self . _send_file ( _message_type , audio , payload )
2017-05-30 22:50:44 +03:00
async def send_document ( self , chat_id , document , caption = None , disable_notification = None , reply_to_message_id = None ,
reply_markup = None ) :
2017-05-30 22:57:20 +03:00
_message_type = ' document '
2017-05-30 22:50:44 +03:00
if reply_markup and hasattr ( reply_markup , ' to_json ' ) :
reply_markup = json . dumps ( reply_markup . to_json ( ) )
if hasattr ( reply_to_message_id , ' message_id ' ) :
reply_to_message_id = reply_to_message_id . message_id
2017-05-30 22:57:20 +03:00
payload = generate_payload ( * * locals ( ) , exclude = [ _message_type ] )
return await self . _send_file ( _message_type , document , payload )
2017-05-30 22:51:13 +03:00
async def send_sticker ( self , chat_id , sticker , disable_notification = None , reply_to_message_id = None ,
reply_markup = None ) - > Message :
_METHOD = ' sticker '
if reply_markup and hasattr ( reply_markup , ' to_json ' ) :
reply_markup = json . dumps ( reply_markup . to_json ( ) )
if hasattr ( reply_to_message_id , ' message_id ' ) :
reply_to_message_id = reply_to_message_id . message_id
2017-05-30 22:53:36 +03:00
payload = generate_payload ( * * locals ( ) , exclude = [ _METHOD ] )
2017-05-30 22:51:13 +03:00
return await self . _send_file ( _METHOD , sticker , payload )
2017-05-30 22:53:36 +03:00
async def send_video ( self , chat_id , video , duration = None , width = None , height = None , caption = None ,
disable_notification = None , reply_to_message_id = None , reply_markup = None ) - > Message :
2017-05-30 22:57:20 +03:00
_message_type = ' video '
if reply_markup and hasattr ( reply_markup , ' to_json ' ) :
reply_markup = json . dumps ( reply_markup . to_json ( ) )
if hasattr ( reply_to_message_id , ' message_id ' ) :
reply_to_message_id = reply_to_message_id . message_id
payload = generate_payload ( * * locals ( ) , exclude = [ _message_type ] )
return await self . _send_file ( _message_type , video , payload )
async def send_voice ( self , chat_id , voice , caption = None , duration = None , disable_notification = None ,
reply_to_message_id = None , reply_markup = None ) - > Message :
_message_type = ' voice '
2017-05-30 22:53:36 +03:00
if reply_markup and hasattr ( reply_markup , ' to_json ' ) :
reply_markup = json . dumps ( reply_markup . to_json ( ) )
if hasattr ( reply_to_message_id , ' message_id ' ) :
reply_to_message_id = reply_to_message_id . message_id
2017-05-30 22:57:20 +03:00
payload = generate_payload ( * * locals ( ) , exclude = [ _message_type ] )
return await self . _send_file ( _message_type , voice , payload )
2017-05-30 23:05:33 +03:00
async def send_video_note ( self , chat_id , video_note , duration = None , length = None , disable_notification = None ,
reply_to_message_id = None , reply_markup = None ) - > Message :
_message_type = ' video_note '
if reply_markup and hasattr ( reply_markup , ' to_json ' ) :
reply_markup = json . dumps ( reply_markup . to_json ( ) )
if hasattr ( reply_to_message_id , ' message_id ' ) :
reply_to_message_id = reply_to_message_id . message_id
payload = generate_payload ( * * locals ( ) , exclude = [ _message_type ] )
return await self . _send_file ( _message_type , video_note , payload )
2017-05-30 23:09:17 +03:00
async def send_location ( self , chat_id , latitude , longitude , disable_notification = None , reply_to_message_id = None ,
reply_markup = None ) :
if reply_markup and hasattr ( reply_markup , ' to_json ' ) :
reply_markup = json . dumps ( reply_markup . to_json ( ) )
if hasattr ( reply_to_message_id , ' message_id ' ) :
reply_to_message_id = reply_to_message_id . message_id
payload = generate_payload ( * * locals ( ) )
message = await self . request ( ApiMethods . SEND_LOCATION , payload )
return self . prepare_object ( Message . de_json ( message ) )
2017-05-30 23:11:56 +03:00
async def send_venue ( self , chat_id , latitude , longitude , title , address , foursquare_id , disable_notification = None ,
reply_to_message_id = None , reply_markup = None ) :
if reply_markup and hasattr ( reply_markup , ' to_json ' ) :
reply_markup = json . dumps ( reply_markup . to_json ( ) )
if hasattr ( reply_to_message_id , ' message_id ' ) :
reply_to_message_id = reply_to_message_id . message_id
payload = generate_payload ( * * locals ( ) )
message = await self . request ( ApiMethods . SEND_VENUE , payload )
return self . prepare_object ( Message . de_json ( message ) )
2017-05-30 23:16:03 +03:00
async def send_contact ( self , chat_id , phone_number , first_name , last_name = None , disable_notification = None ,
reply_to_message_id = None , reply_markup = None ) :
if reply_markup and hasattr ( reply_markup , ' to_json ' ) :
reply_markup = json . dumps ( reply_markup . to_json ( ) )
if hasattr ( reply_to_message_id , ' message_id ' ) :
reply_to_message_id = reply_to_message_id . message_id
payload = generate_payload ( * * locals ( ) )
message = await self . request ( ApiMethods . SEND_CONTACT , payload )
return self . prepare_object ( Message . de_json ( message ) )
async def send_chat_action ( self , chat_id , action ) :
payload = generate_payload ( * * locals ( ) )
message = await self . request ( ApiMethods . SEND_CHAT_ACTION , payload )
return self . prepare_object ( Message . de_json ( message ) )
2017-05-30 23:18:47 +03:00
async def get_user_profile_photos ( self , user_id , offset = None , limit = None ) :
payload = generate_payload ( * * locals ( ) )
message = await self . request ( ApiMethods . GET_USER_PROFILE_PHOTOS , payload )
return self . prepare_object ( UserProfilePhotos . de_json ( message ) )
2017-05-30 23:22:20 +03:00
async def get_file ( self , file_id ) :
payload = generate_payload ( * * locals ( ) )
message = await self . request ( ApiMethods . GET_FILE , payload )
return self . prepare_object ( File . de_json ( message ) )
2017-06-02 01:28:00 +03:00
async def kick_chat_user ( self , chat_id , user_id ) :
payload = generate_payload ( * * locals ( ) )
2017-06-02 01:31:35 +03:00
return await self . request ( ApiMethods . KICK_CHAT_MEMBER , payload )
2017-06-02 01:28:00 +03:00
async def unban_chat_member ( self , chat_id , user_id ) :
payload = generate_payload ( * * locals ( ) )
2017-06-02 01:31:35 +03:00
return await self . request ( ApiMethods . UNBAN_CHAT_MEMBER , payload )
2017-06-02 01:30:44 +03:00
async def leave_chat ( self , chat_id ) :
payload = generate_payload ( * * locals ( ) )
2017-06-02 01:31:35 +03:00
return await self . request ( ApiMethods . LEAVE_CHAT , payload )
2017-06-02 01:32:12 +03:00
async def get_chat ( self , chat_id ) - > Chat :
payload = generate_payload ( * * locals ( ) )
raw = await self . request ( ApiMethods . GET_CHAT , payload )
return self . prepare_object ( Chat . de_json ( raw ) )
2017-06-02 01:34:27 +03:00
async def get_chat_administrators ( self , chat_id ) :
payload = generate_payload ( * * locals ( ) )
raw = await self . request ( ApiMethods . GET_CHAT_ADMINISTRATORS , payload )
return [ self . prepare_object ( ChatMember . de_json ( raw_chat_member ) ) for raw_chat_member in raw ]