2015-06-26 09:55:13 +03:00
# -*- coding: utf-8 -*-
2017-06-22 06:35:13 +03:00
try :
import ujson as json
except ImportError :
import json
2015-06-26 09:55:13 +03:00
import requests
2017-05-25 05:56:58 +03:00
2017-01-30 17:40:18 +03:00
try :
from requests . packages . urllib3 import fields
2017-05-25 05:56:58 +03:00
2017-04-02 10:56:53 +03:00
format_header_param = fields . format_header_param
2017-01-30 17:40:18 +03:00
except ImportError :
2017-04-02 10:56:53 +03:00
format_header_param = None
2015-06-30 06:49:35 +03:00
import telebot
2015-06-30 08:20:44 +03:00
from telebot import types
2015-08-31 12:46:18 +03:00
from telebot import util
2015-06-30 06:49:35 +03:00
2015-07-20 04:56:17 +03:00
logger = telebot . logger
2017-06-28 12:44:07 +03:00
proxy = None
2015-07-20 04:56:17 +03:00
2015-09-18 21:53:10 +03:00
API_URL = " https://api.telegram.org/bot {0} / {1} "
FILE_URL = " https://api.telegram.org/file/bot {0} / {1} "
2015-06-26 17:35:52 +03:00
2016-04-14 09:34:37 +03:00
CONNECT_TIMEOUT = 3.5
READ_TIMEOUT = 9999
2015-09-18 21:53:10 +03:00
2017-07-19 01:35:44 +03:00
def _get_req_session ( ) :
return util . per_thread ( ' req_session ' , lambda : requests . session ( ) )
2015-09-18 21:53:10 +03:00
def _make_request ( token , method_name , method = ' get ' , params = None , files = None , base_url = API_URL ) :
2015-07-02 14:43:49 +03:00
"""
Makes a request to the Telegram API .
: param token : The bot ' s API token. (Created with @BotFather)
: param method_name : Name of the API method to be called . ( E . g . ' getUpdates ' )
: param method : HTTP method to be used . Defaults to ' get ' .
: param params : Optional parameters . Should be a dictionary with key - value pairs .
: param files : Optional files .
2015-08-19 22:29:17 +03:00
: return : The result parsed to a JSON dictionary .
2015-07-02 14:43:49 +03:00
"""
2015-09-18 21:53:10 +03:00
request_url = base_url . format ( token , method_name )
2015-09-08 23:34:55 +03:00
logger . debug ( " Request: method= {0} url= {1} params= {2} files= {3} " . format ( method , request_url , params , files ) )
2016-04-14 09:34:37 +03:00
read_timeout = READ_TIMEOUT
2016-05-22 19:35:20 +03:00
connect_timeout = CONNECT_TIMEOUT
2017-04-02 10:56:53 +03:00
if files and format_header_param :
fields . format_header_param = _no_encode ( format_header_param )
2016-04-14 09:34:37 +03:00
if params :
if ' timeout ' in params : read_timeout = params [ ' timeout ' ] + 10
2016-05-22 19:35:20 +03:00
if ' connect-timeout ' in params : connect_timeout = params [ ' connect-timeout ' ] + 10
2017-07-19 15:44:10 +03:00
result = _get_req_session ( ) . request ( method , request_url , params = params , files = files ,
2017-07-19 01:35:44 +03:00
timeout = ( connect_timeout , read_timeout ) , proxies = proxy )
2015-09-18 21:53:10 +03:00
logger . debug ( " The server returned: ' {0} ' " . format ( result . text . encode ( ' utf8 ' ) ) )
2015-08-19 22:29:17 +03:00
return _check_result ( method_name , result ) [ ' result ' ]
def _check_result ( method_name , result ) :
"""
Checks whether ` result ` is a valid API response .
A result is considered invalid if :
- The server returned an HTTP response code other than 200
- The content of the result is invalid JSON .
- The method call was unsuccessful ( The JSON ' ok ' field equals False )
: raises ApiException : if one of the above listed cases is applicable
: param method_name : The name of the method called
: param result : The returned result of the method request
: return : The result parsed to a JSON dictionary .
"""
2015-07-01 23:16:13 +03:00
if result . status_code != 200 :
2016-01-05 09:07:47 +03:00
msg = ' The server returned HTTP {0} {1} . Response body: \n [ {2} ] ' \
2015-10-06 23:36:57 +03:00
. format ( result . status_code , result . reason , result . text . encode ( ' utf8 ' ) )
2015-08-19 22:29:17 +03:00
raise ApiException ( msg , method_name , result )
2015-07-01 23:16:13 +03:00
try :
result_json = result . json ( )
except :
2016-01-05 09:07:47 +03:00
msg = ' The server returned an invalid JSON response. Response body: \n [ {0} ] ' \
2015-10-06 23:36:57 +03:00
. format ( result . text . encode ( ' utf8 ' ) )
2015-08-19 22:29:17 +03:00
raise ApiException ( msg , method_name , result )
if not result_json [ ' ok ' ] :
2016-01-05 09:07:47 +03:00
msg = ' Error code: {0} Description: {1} ' \
2015-08-19 22:29:17 +03:00
. format ( result_json [ ' error_code ' ] , result_json [ ' description ' ] )
raise ApiException ( msg , method_name , result )
return result_json
2015-07-01 23:16:13 +03:00
2015-06-26 10:46:02 +03:00
def get_me ( token ) :
2015-11-08 05:30:09 +03:00
method_url = r ' getMe '
2015-07-01 23:16:13 +03:00
return _make_request ( token , method_url )
2015-06-26 09:55:13 +03:00
2015-09-18 21:53:10 +03:00
2015-09-18 21:31:29 +03:00
def get_file ( token , file_id ) :
2015-11-08 05:30:09 +03:00
method_url = r ' getFile '
2015-09-18 21:31:29 +03:00
return _make_request ( token , method_url , params = { ' file_id ' : file_id } )
2015-06-26 17:35:52 +03:00
2015-09-18 21:53:10 +03:00
def download_file ( token , file_path ) :
url = FILE_URL . format ( token , file_path )
2017-07-19 01:35:44 +03:00
result = _get_req_session ( ) . get ( url )
2015-09-18 21:53:10 +03:00
if result . status_code != 200 :
2016-01-05 09:07:47 +03:00
msg = ' The server returned HTTP {0} {1} . Response body: \n [ {2} ] ' \
2015-09-18 21:53:10 +03:00
. format ( result . status_code , result . reason , result . text )
raise ApiException ( msg , ' Download file ' , result )
return result . content
2015-09-08 22:51:45 +03:00
def send_message ( token , chat_id , text , disable_web_page_preview = None , reply_to_message_id = None , reply_markup = None ,
2016-02-27 06:17:35 +03:00
parse_mode = None , disable_notification = None ) :
2015-06-26 10:46:02 +03:00
"""
Use this method to send text messages . On success , the sent Message is returned .
: param token :
: param chat_id :
: param text :
: param disable_web_page_preview :
: param reply_to_message_id :
: param reply_markup :
: return :
"""
2015-06-26 09:55:13 +03:00
method_url = r ' sendMessage '
2015-06-26 10:19:05 +03:00
payload = { ' chat_id ' : str ( chat_id ) , ' text ' : text }
2015-06-26 09:55:13 +03:00
if disable_web_page_preview :
2015-06-26 10:19:05 +03:00
payload [ ' disable_web_page_preview ' ] = disable_web_page_preview
2015-06-26 09:55:13 +03:00
if reply_to_message_id :
2015-06-26 10:19:05 +03:00
payload [ ' reply_to_message_id ' ] = reply_to_message_id
2015-06-26 09:55:13 +03:00
if reply_markup :
2015-07-02 14:43:49 +03:00
payload [ ' reply_markup ' ] = _convert_markup ( reply_markup )
2015-09-08 22:51:45 +03:00
if parse_mode :
payload [ ' parse_mode ' ] = parse_mode
2016-02-27 06:17:35 +03:00
if disable_notification :
payload [ ' disable_notification ' ] = disable_notification
2015-07-25 21:59:36 +03:00
return _make_request ( token , method_url , params = payload , method = ' post ' )
2015-06-26 13:02:30 +03:00
2015-06-26 17:35:52 +03:00
2016-12-06 06:42:15 +03:00
def set_webhook ( token , url = None , certificate = None , max_connections = None , allowed_updates = None ) :
2015-11-08 05:30:09 +03:00
method_url = r ' setWebhook '
2015-09-18 21:12:53 +03:00
payload = {
' url ' : url if url else " " ,
}
files = None
if certificate :
files = { ' certificate ' : certificate }
2016-12-06 06:42:15 +03:00
if max_connections :
payload [ ' max_connections ' ] = max_connections
if allowed_updates :
2017-06-22 06:35:13 +03:00
payload [ ' allowed_updates ' ] = json . dumps ( allowed_updates )
2015-09-18 21:12:53 +03:00
return _make_request ( token , method_url , params = payload , files = files )
2016-12-06 06:52:16 +03:00
def delete_webhook ( token ) :
method_url = r ' deleteWebhook '
return _make_request ( token , method_url )
2016-10-20 10:52:38 +03:00
def get_webhook_info ( token ) :
method_url = r ' getWebhookInfo '
payload = { }
return _make_request ( token , method_url , params = payload )
2016-12-06 06:44:30 +03:00
def get_updates ( token , offset = None , limit = None , timeout = None , allowed_updates = None ) :
2015-06-26 13:02:30 +03:00
method_url = r ' getUpdates '
2015-07-02 23:32:18 +03:00
payload = { }
if offset :
payload [ ' offset ' ] = offset
if limit :
payload [ ' limit ' ] = limit
if timeout :
payload [ ' timeout ' ] = timeout
2016-12-06 06:44:30 +03:00
if allowed_updates :
2017-06-22 06:35:13 +03:00
payload [ ' allowed_updates ' ] = json . dumps ( allowed_updates )
2015-07-02 23:32:18 +03:00
return _make_request ( token , method_url , params = payload )
2015-06-26 17:16:11 +03:00
2015-07-01 23:34:40 +03:00
2015-06-30 17:40:44 +03:00
def get_user_profile_photos ( token , user_id , offset = None , limit = None ) :
method_url = r ' getUserProfilePhotos '
payload = { ' user_id ' : user_id }
if offset :
payload [ ' offset ' ] = offset
if limit :
payload [ ' limit ' ] = limit
2015-07-01 23:16:13 +03:00
return _make_request ( token , method_url , params = payload )
2015-06-30 17:40:44 +03:00
2015-06-26 17:35:52 +03:00
2016-06-07 14:00:44 +03:00
def get_chat ( token , chat_id ) :
method_url = r ' getChat '
payload = { ' chat_id ' : chat_id }
return _make_request ( token , method_url , params = payload )
def leave_chat ( token , chat_id ) :
method_url = r ' leaveChat '
payload = { ' chat_id ' : chat_id }
return _make_request ( token , method_url , params = payload )
def get_chat_administrators ( token , chat_id ) :
method_url = r ' getChatAdministrators '
payload = { ' chat_id ' : chat_id }
return _make_request ( token , method_url , params = payload )
def get_chat_members_count ( token , chat_id ) :
method_url = r ' getChatMembersCount '
payload = { ' chat_id ' : chat_id }
return _make_request ( token , method_url , params = payload )
def get_chat_member ( token , chat_id , user_id ) :
method_url = r ' getChatMember '
payload = { ' chat_id ' : chat_id , ' user_id ' : user_id }
return _make_request ( token , method_url , params = payload )
2016-02-27 06:17:35 +03:00
def forward_message ( token , chat_id , from_chat_id , message_id , disable_notification = None ) :
2015-06-26 17:16:11 +03:00
method_url = r ' forwardMessage '
2015-06-26 17:35:52 +03:00
payload = { ' chat_id ' : chat_id , ' from_chat_id ' : from_chat_id , ' message_id ' : message_id }
2016-02-27 06:17:35 +03:00
if disable_notification :
payload [ ' disable_notification ' ] = disable_notification
2015-07-01 23:16:13 +03:00
return _make_request ( token , method_url , params = payload )
2015-06-26 20:53:07 +03:00
2016-02-27 06:17:35 +03:00
def send_photo ( token , chat_id , photo , caption = None , reply_to_message_id = None , reply_markup = None ,
disable_notification = None ) :
2015-06-26 20:53:07 +03:00
method_url = r ' sendPhoto '
payload = { ' chat_id ' : chat_id }
2015-07-14 08:24:32 +03:00
files = None
2015-08-31 12:46:18 +03:00
if not util . is_string ( photo ) :
2015-07-14 08:24:32 +03:00
files = { ' photo ' : photo }
else :
payload [ ' photo ' ] = photo
2015-06-26 20:53:07 +03:00
if caption :
payload [ ' caption ' ] = caption
if reply_to_message_id :
payload [ ' reply_to_message_id ' ] = reply_to_message_id
if reply_markup :
2015-07-02 14:43:49 +03:00
payload [ ' reply_markup ' ] = _convert_markup ( reply_markup )
2016-02-27 06:17:35 +03:00
if disable_notification :
payload [ ' disable_notification ' ] = disable_notification
2015-07-01 23:16:13 +03:00
return _make_request ( token , method_url , params = payload , files = files , method = ' post ' )
2015-06-27 16:55:45 +03:00
2015-06-26 20:53:07 +03:00
2016-02-27 06:17:35 +03:00
def send_location ( token , chat_id , latitude , longitude , reply_to_message_id = None , reply_markup = None ,
disable_notification = None ) :
2015-06-27 17:11:18 +03:00
method_url = r ' sendLocation '
payload = { ' chat_id ' : chat_id , ' latitude ' : latitude , ' longitude ' : longitude }
if reply_to_message_id :
payload [ ' reply_to_message_id ' ] = reply_to_message_id
if reply_markup :
2015-07-02 14:43:49 +03:00
payload [ ' reply_markup ' ] = _convert_markup ( reply_markup )
2016-02-27 06:17:35 +03:00
if disable_notification :
payload [ ' disable_notification ' ] = disable_notification
2015-07-01 23:16:13 +03:00
return _make_request ( token , method_url , params = payload )
2015-06-27 17:11:18 +03:00
2015-06-30 06:54:04 +03:00
2016-04-14 08:55:28 +03:00
def send_venue ( token , chat_id , latitude , longitude , title , address , foursquare_id = None , disable_notification = None ,
reply_to_message_id = None , reply_markup = None ) :
method_url = r ' sendVenue '
payload = { ' chat_id ' : chat_id , ' latitude ' : latitude , ' longitude ' : longitude , ' title ' : title , ' address ' : address }
if foursquare_id :
payload [ ' foursquare_id ' ] = foursquare_id
if disable_notification :
payload [ ' disable_notification ' ] = disable_notification
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 )
2016-04-16 10:07:52 +03:00
def send_contact ( token , chat_id , phone_number , first_name , last_name = None , disable_notification = None ,
reply_to_message_id = None , reply_markup = None ) :
method_url = r ' sendContact '
payload = { ' chat_id ' : chat_id , ' phone_number ' : phone_number , ' first_name ' : first_name }
if last_name :
payload [ ' last_name ' ] = last_name
if disable_notification :
payload [ ' disable_notification ' ] = disable_notification
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 )
2016-04-14 08:55:28 +03:00
2015-06-30 06:54:04 +03:00
def send_chat_action ( token , chat_id , action ) :
2015-06-28 12:56:32 +03:00
method_url = r ' sendChatAction '
payload = { ' chat_id ' : chat_id , ' action ' : action }
2015-07-01 23:16:13 +03:00
return _make_request ( token , method_url , params = payload )
2015-06-27 17:11:18 +03:00
2015-06-30 06:54:04 +03:00
2016-02-27 06:17:35 +03:00
def send_video ( token , chat_id , data , duration = None , caption = None , reply_to_message_id = None , reply_markup = None ,
2016-05-22 19:35:20 +03:00
disable_notification = None , timeout = None ) :
2015-08-01 05:12:15 +03:00
method_url = r ' sendVideo '
payload = { ' chat_id ' : chat_id }
files = None
2015-08-31 12:46:18 +03:00
if not util . is_string ( data ) :
2015-08-01 05:12:15 +03:00
files = { ' video ' : data }
else :
payload [ ' video ' ] = data
if duration :
payload [ ' duration ' ] = duration
if caption :
payload [ ' caption ' ] = caption
if reply_to_message_id :
payload [ ' reply_to_message_id ' ] = reply_to_message_id
if reply_markup :
payload [ ' reply_markup ' ] = _convert_markup ( reply_markup )
2016-02-27 06:17:35 +03:00
if disable_notification :
payload [ ' disable_notification ' ] = disable_notification
2016-05-22 19:35:20 +03:00
if timeout :
payload [ ' connect-timeout ' ] = timeout
2015-08-01 05:12:15 +03:00
return _make_request ( token , method_url , params = payload , files = files , method = ' post ' )
2016-10-11 22:51:20 +03:00
def send_voice ( token , chat_id , voice , caption = None , duration = None , reply_to_message_id = None , reply_markup = None ,
2016-05-22 19:35:20 +03:00
disable_notification = None , timeout = None ) :
2015-08-19 13:08:01 +03:00
method_url = r ' sendVoice '
payload = { ' chat_id ' : chat_id }
files = None
2015-08-31 12:46:18 +03:00
if not util . is_string ( voice ) :
2015-08-19 13:08:01 +03:00
files = { ' voice ' : voice }
else :
payload [ ' voice ' ] = voice
2016-10-11 22:51:20 +03:00
if caption :
payload [ ' caption ' ] = caption
2015-08-19 13:08:01 +03:00
if duration :
payload [ ' duration ' ] = duration
if reply_to_message_id :
payload [ ' reply_to_message_id ' ] = reply_to_message_id
if reply_markup :
payload [ ' reply_markup ' ] = _convert_markup ( reply_markup )
2016-02-27 06:17:35 +03:00
if disable_notification :
payload [ ' disable_notification ' ] = disable_notification
2016-05-22 19:35:20 +03:00
if timeout :
payload [ ' connect-timeout ' ] = timeout
2015-08-19 13:08:01 +03:00
return _make_request ( token , method_url , params = payload , files = files , method = ' post ' )
2017-05-19 17:19:15 +03:00
def send_video_note ( token , chat_id , data , duration = None , length = None , reply_to_message_id = None , reply_markup = None ,
disable_notification = None , timeout = None ) :
method_url = r ' sendVideoNote '
payload = { ' chat_id ' : chat_id }
files = None
if not util . is_string ( data ) :
files = { ' video_note ' : data }
else :
payload [ ' video_note ' ] = data
if duration :
payload [ ' duration ' ] = duration
if length :
payload [ ' length ' ] = length
2017-05-19 18:08:07 +03:00
else :
payload [ ' length ' ] = 639 # seems like it is MAX length size
2017-05-19 17:19:15 +03:00
if reply_to_message_id :
payload [ ' reply_to_message_id ' ] = reply_to_message_id
if reply_markup :
payload [ ' reply_markup ' ] = _convert_markup ( reply_markup )
if disable_notification :
payload [ ' disable_notification ' ] = disable_notification
if timeout :
payload [ ' connect-timeout ' ] = timeout
return _make_request ( token , method_url , params = payload , files = files , method = ' post ' )
2016-10-11 22:51:20 +03:00
def send_audio ( token , chat_id , audio , caption = None , duration = None , performer = None , title = None , reply_to_message_id = None ,
2016-05-22 19:35:20 +03:00
reply_markup = None , disable_notification = None , timeout = None ) :
2015-08-19 13:08:01 +03:00
method_url = r ' sendAudio '
payload = { ' chat_id ' : chat_id }
files = None
2015-08-31 12:46:18 +03:00
if not util . is_string ( audio ) :
2015-08-19 13:08:01 +03:00
files = { ' audio ' : audio }
else :
payload [ ' audio ' ] = audio
2016-10-11 22:51:20 +03:00
if caption :
payload [ ' caption ' ] = caption
2015-08-19 13:08:01 +03:00
if duration :
payload [ ' duration ' ] = duration
if performer :
payload [ ' performer ' ] = performer
if title :
payload [ ' title ' ] = title
if reply_to_message_id :
payload [ ' reply_to_message_id ' ] = reply_to_message_id
if reply_markup :
payload [ ' reply_markup ' ] = _convert_markup ( reply_markup )
2016-02-27 06:17:35 +03:00
if disable_notification :
payload [ ' disable_notification ' ] = disable_notification
2016-05-22 19:35:20 +03:00
if timeout :
payload [ ' connect-timeout ' ] = timeout
2015-08-19 13:08:01 +03:00
return _make_request ( token , method_url , params = payload , files = files , method = ' post ' )
2016-06-02 08:15:22 +03:00
def send_data ( token , chat_id , data , data_type , reply_to_message_id = None , reply_markup = None , disable_notification = None ,
timeout = None , caption = None ) :
2015-06-26 21:14:45 +03:00
method_url = get_method_by_type ( data_type )
2015-06-26 20:53:07 +03:00
payload = { ' chat_id ' : chat_id }
2015-07-14 08:24:32 +03:00
files = None
2015-08-31 12:46:18 +03:00
if not util . is_string ( data ) :
2015-07-14 08:24:32 +03:00
files = { data_type : data }
else :
payload [ data_type ] = data
2015-06-26 20:53:07 +03:00
if reply_to_message_id :
payload [ ' reply_to_message_id ' ] = reply_to_message_id
if reply_markup :
2015-07-02 14:43:49 +03:00
payload [ ' reply_markup ' ] = _convert_markup ( reply_markup )
2016-02-27 06:17:35 +03:00
if disable_notification :
payload [ ' disable_notification ' ] = disable_notification
2016-05-22 19:35:20 +03:00
if timeout :
payload [ ' connect-timeout ' ] = timeout
2016-06-02 08:15:22 +03:00
if caption :
payload [ ' caption ' ] = caption
2015-07-01 23:16:13 +03:00
return _make_request ( token , method_url , params = payload , files = files , method = ' post ' )
2015-06-27 16:55:45 +03:00
2015-06-26 20:53:07 +03:00
2015-06-26 21:14:45 +03:00
def get_method_by_type ( data_type ) :
if data_type == ' document ' :
2015-11-08 05:30:09 +03:00
return r ' sendDocument '
2015-06-26 21:14:45 +03:00
if data_type == ' sticker ' :
2015-11-08 05:30:09 +03:00
return r ' sendSticker '
2015-06-27 16:55:45 +03:00
2017-07-01 06:11:25 +03:00
def kick_chat_member ( token , chat_id , user_id , until_date = None ) :
2016-04-14 09:48:26 +03:00
method_url = ' kickChatMember '
payload = { ' chat_id ' : chat_id , ' user_id ' : user_id }
2017-07-01 06:11:25 +03:00
if until_date :
payload [ ' until_date ' ] = until_date
2016-04-14 09:48:26 +03:00
return _make_request ( token , method_url , params = payload , method = ' post ' )
def unban_chat_member ( token , chat_id , user_id ) :
method_url = ' unbanChatMember '
payload = { ' chat_id ' : chat_id , ' user_id ' : user_id }
return _make_request ( token , method_url , params = payload , method = ' post ' )
2017-07-02 16:08:36 +03:00
def restrict_chat_member ( token , chat_id , user_id , until_date = None , can_send_messages = None ,
can_send_media_messages = None , can_send_other_messages = None ,
can_add_web_page_previews = None ) :
2017-06-30 19:47:09 +03:00
method_url = ' restrictChatMember '
2017-07-02 16:08:36 +03:00
payload = { ' chat_id ' : chat_id , ' user_id ' : user_id }
if until_date :
payload [ ' until_date ' ] = until_date
if can_send_messages :
payload [ ' can_send_messages ' ] = can_send_messages
if can_send_media_messages :
payload [ ' can_send_media_messages ' ] = can_send_media_messages
if can_send_other_messages :
payload [ ' can_send_other_messages ' ] = can_send_other_messages
if can_add_web_page_previews :
payload [ ' can_add_web_page_previews ' ] = can_add_web_page_previews
2017-06-30 19:47:09 +03:00
return _make_request ( token , method_url , params = payload , method = ' post ' )
2017-07-02 16:08:36 +03:00
def promote_chat_member ( token , chat_id , user_id , can_change_info = None , can_post_messages = None ,
can_edit_messages = None , can_delete_messages = None , can_invite_users = None ,
can_restrict_members = None , can_pin_messages = None , can_promote_members = None ) :
2017-06-30 19:47:09 +03:00
method_url = ' promoteChatMember '
2017-07-02 16:08:36 +03:00
payload = { ' chat_id ' : chat_id , ' user_id ' : user_id }
if can_change_info :
payload [ ' can_change_info ' ] = can_change_info
if can_post_messages :
payload [ ' can_post_messages ' ] = can_post_messages
if can_edit_messages :
payload [ ' can_edit_messages ' ] = can_edit_messages
if can_delete_messages :
payload [ ' can_delete_messages ' ] = can_delete_messages
if can_invite_users :
payload [ ' can_invite_users ' ] = can_invite_users
if can_restrict_members :
payload [ ' can_restrict_members ' ] = can_restrict_members
if can_pin_messages :
payload [ ' can_pin_messages ' ] = can_pin_messages
if can_promote_members :
payload [ ' can_promote_members ' ] = can_promote_members
2017-06-30 19:47:09 +03:00
return _make_request ( token , method_url , params = payload , method = ' post ' )
def export_chat_invite_link ( token , chat_id ) :
method_url = ' exportChatInviteLink '
payload = { ' chat_id ' : chat_id }
return _make_request ( token , method_url , params = payload , method = ' post ' )
def set_chat_photo ( token , chat_id , photo ) :
method_url = ' setChatPhoto '
payload = { ' chat_id ' : chat_id }
files = None
if not util . is_string ( photo ) :
files = { ' photo ' : photo }
else :
payload [ ' photo ' ] = photo
return _make_request ( token , method_url , params = payload , files = files , method = ' post ' )
def delete_chat_photo ( token , chat_id ) :
method_url = ' deleteChatPhoto '
payload = { ' chat_id ' : chat_id }
return _make_request ( token , method_url , params = payload , method = ' post ' )
def set_chat_title ( token , chat_id , title ) :
method_url = ' setChatTitle '
payload = { ' chat_id ' : chat_id , ' title ' : title }
return _make_request ( token , method_url , params = payload , method = ' post ' )
def set_chat_description ( token , chat_id , description ) :
method_url = ' setChatDescription '
payload = { ' chat_id ' : chat_id , ' description ' : description }
return _make_request ( token , method_url , params = payload , method = ' post ' )
def pin_chat_message ( token , chat_id , message_id , disable_notification = False ) :
method_url = ' pinChatMessage '
payload = { ' chat_id ' : chat_id , ' message_id ' : message_id , ' disable_notification ' : disable_notification }
return _make_request ( token , method_url , params = payload , method = ' post ' )
def unpin_chat_message ( token , chat_id ) :
method_url = ' unpinChatMessage '
payload = { ' chat_id ' : chat_id }
return _make_request ( token , method_url , params = payload , method = ' post ' )
2016-04-14 10:03:07 +03:00
# Updating messages
2016-04-14 10:06:46 +03:00
def edit_message_text ( token , text , chat_id = None , message_id = None , inline_message_id = None , parse_mode = None ,
2016-04-14 10:03:07 +03:00
disable_web_page_preview = None , reply_markup = None ) :
method_url = r ' editMessageText '
2016-04-14 10:06:46 +03:00
payload = { ' text ' : text }
if chat_id :
payload [ ' chat_id ' ] = chat_id
2016-04-14 10:03:07 +03:00
if message_id :
payload [ ' message_id ' ] = message_id
if inline_message_id :
payload [ ' inline_message_id ' ] = inline_message_id
if parse_mode :
payload [ ' parse_mode ' ] = parse_mode
if disable_web_page_preview :
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 )
2016-04-14 10:17:53 +03:00
def edit_message_caption ( token , caption , chat_id = None , message_id = None , inline_message_id = None , reply_markup = None ) :
method_url = r ' editMessageCaption '
payload = { ' caption ' : caption }
if chat_id :
payload [ ' chat_id ' ] = chat_id
if message_id :
payload [ ' message_id ' ] = message_id
if inline_message_id :
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 )
2016-04-22 20:21:45 +03:00
def edit_message_reply_markup ( token , chat_id = None , message_id = None , inline_message_id = None , reply_markup = None ) :
2016-04-14 10:17:53 +03:00
method_url = r ' editMessageReplyMarkup '
payload = { }
if chat_id :
payload [ ' chat_id ' ] = chat_id
if message_id :
payload [ ' message_id ' ] = message_id
if inline_message_id :
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 )
2017-05-24 01:23:52 +03:00
def delete_message ( token , chat_id , message_id ) :
2017-05-07 17:37:03 +03:00
method_url = r ' deleteMessage '
payload = { ' chat_id ' : chat_id , ' message_id ' : message_id }
return _make_request ( token , method_url , params = payload )
2016-10-08 15:36:48 +03:00
# Game
def send_game ( token , chat_id , game_short_name , disable_notification = None , reply_to_message_id = None , reply_markup = None ) :
method_url = r ' sendGame '
payload = { ' chat_id ' : chat_id , ' game_short_name ' : game_short_name }
if disable_notification :
payload [ ' disable_notification ' ] = disable_notification
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 )
2016-10-26 16:19:04 +03:00
# https://core.telegram.org/bots/api#setgamescore
2016-12-06 06:42:15 +03:00
def set_game_score ( token , user_id , score , force = None , disable_edit_message = None , chat_id = None , message_id = None ,
inline_message_id = None ) :
2016-10-26 16:19:04 +03:00
"""
Use this method to set the score of the specified user in a game . On success , if the message was sent by the bot , returns the edited Message , otherwise returns True . Returns an error , if the new score is not greater than the user ' s current score in the chat.
: param token : Bot ' s token (you don ' t need to fill this )
: param user_id : User identifier
2016-11-21 09:28:32 +03:00
: param score : New score , must be non - negative
: param force : ( Optional ) Pass True , if the high score is allowed to decrease . This can be useful when fixing mistakes or banning cheaters
: param disable_edit_message : ( Optional ) Pass True , if the game message should not be automatically edited to include the current scoreboard
2016-10-26 16:19:04 +03:00
: param chat_id : ( Optional , required if inline_message_id is not specified ) Unique identifier for the target chat ( or username of the target channel in the format @channelusername )
: param message_id : ( Optional , required if inline_message_id is not specified ) Unique identifier of the sent message
: param inline_message_id : ( Optional , required if chat_id and message_id are not specified ) Identifier of the inline message
: return :
"""
method_url = r ' setGameScore '
payload = { ' user_id ' : user_id , ' score ' : score }
2016-11-21 09:28:32 +03:00
if force :
payload [ ' force ' ] = force
2016-10-26 16:19:04 +03:00
if chat_id :
payload [ ' chat_id ' ] = chat_id
if message_id :
payload [ ' message_id ' ] = message_id
if inline_message_id :
payload [ ' inline_message_id ' ] = inline_message_id
2016-11-21 09:28:32 +03:00
if disable_edit_message :
payload [ ' disable_edit_message ' ] = disable_edit_message
2016-10-26 16:19:04 +03:00
return _make_request ( token , method_url , params = payload )
# https://core.telegram.org/bots/api#getgamehighscores
def get_game_high_scores ( token , user_id , chat_id = None , message_id = None , inline_message_id = None ) :
"""
Use this method to get data for high score tables . Will return the score of the specified user and several of his neighbors in a game . On success , returns an Array of GameHighScore objects .
This method will currently return scores for the target user , plus two of his closest neighbors on each side . Will also return the top three users if the user and his neighbors are not among them . Please note that this behavior is subject to change .
: param token : Bot ' s token (you don ' t need to fill this )
: param user_id : Target user id
: param chat_id : ( Optional , required if inline_message_id is not specified ) Unique identifier for the target chat ( or username of the target channel in the format @channelusername )
: param message_id : ( Optional , required if inline_message_id is not specified ) Unique identifier of the sent message
: param inline_message_id : ( Optional , required if chat_id and message_id are not specified ) Identifier of the inline message
: return :
"""
method_url = r ' getGameHighScores '
payload = { ' user_id ' : user_id }
if chat_id :
payload [ ' chat_id ' ] = chat_id
if message_id :
payload [ ' message_id ' ] = message_id
if inline_message_id :
payload [ ' inline_message_id ' ] = inline_message_id
return _make_request ( token , method_url , params = payload )
2017-05-25 05:56:58 +03:00
2017-05-21 16:45:12 +03:00
# Payments (https://core.telegram.org/bots/api#payments)
2017-05-25 05:56:58 +03:00
def send_invoice ( token , chat_id , title , description , invoice_payload , provider_token , currency , prices ,
2017-05-25 06:14:08 +03:00
start_parameter , photo_url = None , photo_size = None , photo_width = None , photo_height = None ,
2017-05-25 05:56:58 +03:00
need_name = None , need_phone_number = None , need_email = None , need_shipping_address = None , is_flexible = None ,
2017-05-24 01:23:52 +03:00
disable_notification = None , reply_to_message_id = None , reply_markup = None ) :
"""
Use this method to send invoices . On success , the sent Message is returned .
: param token : Bot ' s token (you don ' t need to fill this )
: param chat_id : Unique identifier for the target private chat
: param title : Product name
: param description : Product description
2017-05-25 05:56:58 +03:00
: param invoice_payload : Bot - defined invoice payload , 1 - 128 bytes . This will not be displayed to the user , use for your internal processes .
2017-05-24 01:23:52 +03:00
: param provider_token : Payments provider token , obtained via @Botfather
: param currency : Three - letter ISO 4217 currency code , see https : / / core . telegram . org / bots / payments #supported-currencies
: param prices : Price breakdown , a list of components ( e . g . product price , tax , discount , delivery cost , delivery tax , bonus , etc . )
: param start_parameter : Unique deep - linking parameter that can be used to generate this invoice when used as a start parameter
: param photo_url : URL of the product photo for the invoice . Can be a photo of the goods or a marketing image for a service . People like it better when they see what they are paying for .
: param photo_size : Photo size
: param photo_width : Photo width
: param photo_height : Photo height
: param need_name : Pass True , if you require the user ' s full name to complete the order
: param need_phone_number : Pass True , if you require the user ' s phone number to complete the order
: param need_email : Pass True , if you require the user ' s email to complete the order
: param need_shipping_address : Pass True , if you require the user ' s shipping address to complete the order
: param is_flexible : Pass True , if the final price depends on the shipping method
: param disable_notification : Sends the message silently . Users will receive a notification with no sound .
: param reply_to_message_id : If the message is a reply , ID of the original message
: param reply_markup : A JSON - serialized object for an inline keyboard . If empty , one ' Pay total price ' button will be shown . If not empty , the first button must be a Pay button
: return :
"""
method_url = r ' sendInvoice '
2017-05-25 05:56:58 +03:00
payload = { ' chat_id ' : chat_id , ' title ' : title , ' description ' : description , ' payload ' : invoice_payload ,
' provider_token ' : provider_token , ' start_parameter ' : start_parameter , ' currency ' : currency ,
' prices ' : _convert_list_json_serializable ( prices ) }
2017-05-24 01:23:52 +03:00
if photo_url :
payload [ ' photo_url ' ] = photo_url
if photo_size :
payload [ ' photo_size ' ] = photo_size
if photo_width :
payload [ ' photo_width ' ] = photo_width
if photo_height :
payload [ ' photo_height ' ] = photo_height
if need_name :
payload [ ' need_name ' ] = need_name
if need_phone_number :
payload [ ' need_phone_number ' ] = need_phone_number
if need_email :
payload [ ' need_email ' ] = need_email
if need_shipping_address :
payload [ ' need_shipping_address ' ] = need_shipping_address
if is_flexible :
payload [ ' is_flexible ' ] = is_flexible
if disable_notification :
payload [ ' disable_notification ' ] = disable_notification
if reply_to_message_id :
payload [ ' reply_to_message_id ' ] = reply_to_message_id
if reply_markup :
2017-05-25 05:56:58 +03:00
payload [ ' reply_markup ' ] = _convert_markup ( reply_markup )
2017-05-24 01:23:52 +03:00
return _make_request ( token , method_url , params = payload )
2017-05-21 16:45:12 +03:00
2017-05-25 05:56:58 +03:00
def answer_shipping_query ( token , shipping_query_id , ok , shipping_options = None , error_message = None ) :
2017-05-24 01:23:52 +03:00
"""
If you sent an invoice requesting a shipping address and the parameter is_flexible was specified , the Bot API will send an Update with a shipping_query field to the bot . Use this method to reply to shipping queries . On success , True is returned .
: param token : Bot ' s token (you don ' t need to fill this )
: param shipping_query_id : Unique identifier for the query to be answered
: 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 :
"""
method_url = ' answerShippingQuery '
payload = { ' shipping_query_id ' : shipping_query_id , ' ok ' : ok }
if shipping_options :
2017-05-25 05:56:58 +03:00
payload [ ' reply_markup ' ] = _convert_list_json_serializable ( shipping_options )
2017-05-24 01:23:52 +03:00
if error_message :
2017-05-25 05:56:58 +03:00
payload [ ' error_message ' ] = error_message
2017-05-24 01:23:52 +03:00
return _make_request ( token , method_url , params = payload )
def answer_pre_checkout_query ( token , pre_checkout_query_id , ok , error_message = None ) :
"""
Once the user has confirmed their payment and shipping details , the Bot API sends the final confirmation in the form of an Update with the field pre_checkout_query . Use this method to respond to such pre - checkout queries . On success , True is returned . Note : The Bot API must receive an answer within 10 seconds after the pre - checkout query was sent .
: param token : Bot ' s token (you don ' t need to fill this )
: 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 :
"""
method_url = ' answerPreCheckoutQuery '
payload = { ' pre_checkout_query_id ' : pre_checkout_query_id , ' ok ' : ok }
if error_message :
payload [ ' error_message ' ] = error_message
return _make_request ( token , method_url , params = payload )
2017-05-21 16:45:12 +03:00
2016-10-26 16:19:04 +03:00
2016-04-14 10:03:07 +03:00
# InlineQuery
2016-11-21 09:19:59 +03:00
def answer_callback_query ( token , callback_query_id , text = None , show_alert = None , url = None , cache_time = None ) :
"""
Use this method to send answers to callback queries sent from inline keyboards . The answer will be displayed to the user as a notification at the top of the chat screen or as an alert . On success , True is returned .
Alternatively , the user can be redirected to the specified Game URL . For this option to work , you must first create a game for your bot via BotFather and accept the terms . Otherwise , you may use links like telegram . me / your_bot ? start = XXXX that open your bot with a parameter .
: param token : Bot ' s token (you don ' t need to fill this )
: param callback_query_id : Unique identifier for the query to be answered
: param text : ( Optional ) Text of the notification . If not specified , nothing will be shown to the user , 0 - 200 characters
: param show_alert : ( Optional ) If true , an alert will be shown by the client instead of a notification at the top of the chat screen . Defaults to false .
: param url : ( Optional ) URL that will be opened by the user ' s client. If you have created a Game and accepted the conditions via @Botfather, specify the URL that opens your game – note that this will only work if the query comes from a callback_game button.
Otherwise , you may use links like telegram . me / your_bot ? start = XXXX that open your bot with a parameter .
: param cache_time : ( Optional ) The maximum amount of time in seconds that the result of the callback query may be cached client - side . Telegram apps will support caching starting in version 3.14 . Defaults to 0.
: return :
"""
2016-04-14 09:48:26 +03:00
method_url = ' answerCallbackQuery '
payload = { ' callback_query_id ' : callback_query_id }
if text :
payload [ ' text ' ] = text
if show_alert :
payload [ ' show_alert ' ] = show_alert
2016-10-08 16:55:28 +03:00
if url :
payload [ ' url ' ] = url
2016-11-21 09:19:59 +03:00
if cache_time :
payload [ ' cache_time ' ] = cache_time
2016-04-14 09:48:26 +03:00
return _make_request ( token , method_url , params = payload , method = ' post ' )
2016-04-14 10:32:08 +03:00
def answer_inline_query ( token , inline_query_id , results , cache_time = None , is_personal = None , next_offset = None ,
switch_pm_text = None , switch_pm_parameter = None ) :
2016-01-05 09:07:47 +03:00
method_url = ' answerInlineQuery '
2017-05-25 05:56:58 +03:00
payload = { ' inline_query_id ' : inline_query_id , ' results ' : _convert_list_json_serializable ( results ) }
2016-01-05 09:07:47 +03:00
if cache_time :
payload [ ' cache_time ' ] = cache_time
if is_personal :
payload [ ' is_personal ' ] = is_personal
2016-04-17 18:28:47 +03:00
if next_offset is not None :
2016-01-05 09:07:47 +03:00
payload [ ' next_offset ' ] = next_offset
2016-04-14 10:32:08 +03:00
if switch_pm_text :
payload [ ' switch_pm_text ' ] = switch_pm_text
if switch_pm_parameter :
payload [ ' switch_pm_parameter ' ] = switch_pm_parameter
2016-02-13 22:08:37 +03:00
return _make_request ( token , method_url , params = payload , method = ' post ' )
2016-01-05 09:07:47 +03:00
2017-05-25 05:56:58 +03:00
def _convert_list_json_serializable ( results ) :
2016-01-05 09:07:47 +03:00
ret = ' '
for r in results :
if isinstance ( r , types . JsonSerializable ) :
ret = ret + r . to_json ( ) + ' , '
if len ( ret ) > 0 :
ret = ret [ : - 1 ]
return ' [ ' + ret + ' ] '
2015-07-02 14:43:49 +03:00
def _convert_markup ( markup ) :
2015-07-01 23:16:13 +03:00
if isinstance ( markup , types . JsonSerializable ) :
2015-06-30 08:20:44 +03:00
return markup . to_json ( )
2015-07-01 19:17:33 +03:00
return markup
2015-06-27 16:55:45 +03:00
2016-01-05 09:07:47 +03:00
2017-01-30 17:40:18 +03:00
def _no_encode ( func ) :
def wrapper ( key , val ) :
if key == ' filename ' :
return ' {0} = {1} ' . format ( key , val )
else :
return func ( key , val )
2017-05-25 05:56:58 +03:00
2017-01-30 17:40:18 +03:00
return wrapper
2015-07-02 02:18:23 +03:00
class ApiException ( Exception ) :
2015-07-02 14:43:49 +03:00
"""
This class represents an Exception thrown when a call to the Telegram API fails .
2015-08-19 22:29:17 +03:00
In addition to an informative message , it has a ` function_name ` and a ` result ` attribute , which respectively
contain the name of the failed function and the returned result that made the function to be considered as
failed .
2015-07-02 14:43:49 +03:00
"""
2015-07-17 04:35:37 +03:00
2015-08-19 22:29:17 +03:00
def __init__ ( self , msg , function_name , result ) :
super ( ApiException , self ) . __init__ ( " A request to the Telegram API was unsuccessful. {0} " . format ( msg ) )
2015-07-02 14:43:49 +03:00
self . function_name = function_name
2015-06-27 16:55:45 +03:00
self . result = result