2015-06-26 09:55:13 +03:00
# -*- coding: utf-8 -*-
2020-07-30 07:34:51 +03:00
import time
2021-01-16 23:50:25 +03:00
from datetime import datetime
2015-06-26 09:55:13 +03:00
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
2020-07-30 07:34:51 +03:00
from requests . exceptions import HTTPError , ConnectionError , Timeout
2017-05-25 05:56:58 +03:00
2017-01-30 17:40:18 +03:00
try :
2021-07-09 10:42:56 +03:00
# noinspection PyUnresolvedReferences
2017-01-30 17:40:18 +03:00
from requests . packages . urllib3 import fields
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
2020-04-11 13:42:34 +03:00
2017-06-28 12:44:07 +03:00
proxy = None
2020-04-24 21:30:10 +03:00
session = None
2015-07-20 04:56:17 +03:00
2019-08-12 17:09:52 +03:00
API_URL = None
FILE_URL = None
2015-06-26 17:35:52 +03:00
2021-07-09 10:42:56 +03:00
CONNECT_TIMEOUT = 15
READ_TIMEOUT = 30
LONG_POLLING_TIMEOUT = 10 # Should be positive, short polling should be used for testing purposes only (https://core.telegram.org/bots/api#getupdates)
2021-09-11 17:02:40 +03:00
SESSION_TIME_TO_LIVE = 600 # In seconds. None - live forever, 0 - one-time
2016-04-14 09:34:37 +03:00
2020-07-30 07:34:51 +03:00
RETRY_ON_ERROR = False
RETRY_TIMEOUT = 2
MAX_RETRIES = 15
2020-04-11 13:42:34 +03:00
CUSTOM_SERIALIZER = None
2020-04-11 11:02:50 +03:00
ENABLE_MIDDLEWARE = False
2015-09-18 21:53:10 +03:00
2018-09-06 12:42:44 +03:00
def _get_req_session ( reset = False ) :
2021-01-16 23:50:25 +03:00
if SESSION_TIME_TO_LIVE :
# If session TTL is set - check time passed
2021-01-17 00:43:52 +03:00
creation_date = util . per_thread ( ' req_session_time ' , lambda : datetime . now ( ) , reset )
2021-07-09 10:42:56 +03:00
# noinspection PyTypeChecker
2021-01-16 23:50:25 +03:00
if ( datetime . now ( ) - creation_date ) . total_seconds ( ) > SESSION_TIME_TO_LIVE :
# Force session reset
reset = True
2021-01-17 00:43:52 +03:00
# Save reset time
util . per_thread ( ' req_session_time ' , lambda : datetime . now ( ) , True )
2021-01-16 23:50:25 +03:00
if SESSION_TIME_TO_LIVE == 0 :
# Session is one-time use
return requests . sessions . Session ( )
else :
# Session lives some time or forever once created. Default
return util . per_thread ( ' req_session ' , lambda : session if session else requests . sessions . Session ( ) , reset )
2017-07-19 01:35:44 +03:00
2019-11-05 17:37:53 +03:00
def _make_request ( token , method_name , method = ' get ' , params = None , files = None ) :
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
"""
2021-06-19 15:09:52 +03:00
if not token :
raise Exception ( ' Bot token is not defined ' )
2020-11-07 12:52:51 +03:00
if API_URL :
2021-07-09 10:42:56 +03:00
# noinspection PyUnresolvedReferences
2019-11-05 17:37:53 +03:00
request_url = API_URL . format ( token , method_name )
2020-11-07 12:52:51 +03:00
else :
request_url = " https://api.telegram.org/bot {0} / {1} " . format ( token , method_name )
2021-01-17 03:26:38 +03:00
logger . debug ( " Request: method= {0} url= {1} params= {2} files= {3} " . format ( method , request_url , params , files ) . replace ( token , token . split ( ' : ' ) [ 0 ] + " : {TOKEN} " ) )
2020-07-11 20:09:48 +03:00
read_timeout = READ_TIMEOUT
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 :
2020-05-16 17:34:56 +03:00
if ' timeout ' in params :
2021-07-09 10:42:56 +03:00
read_timeout = params . pop ( ' timeout ' )
connect_timeout = read_timeout
# if 'connect-timeout' in params:
# connect_timeout = params.pop('connect-timeout') + 10
2020-11-07 12:52:51 +03:00
if ' long_polling_timeout ' in params :
2021-07-09 10:42:56 +03:00
# For getUpdates: it's the only function with timeout parameter on the BOT API side
long_polling_timeout = params . pop ( ' long_polling_timeout ' )
params [ ' timeout ' ] = long_polling_timeout
# Long polling hangs for a given time. Read timeout should be greater that long_polling_timeout
read_timeout = max ( long_polling_timeout + 5 , read_timeout )
# Lets stop suppose that user is stupid and assume that he knows what he do...
# read_timeout = read_timeout + 10
# connect_timeout = connect_timeout + 10
2020-11-07 12:52:51 +03:00
2021-07-09 10:42:56 +03:00
params = params or None # Set params to None if empty
2020-11-07 12:52:51 +03:00
result = None
2020-07-30 07:34:51 +03:00
if RETRY_ON_ERROR :
got_result = False
current_try = 0
while not got_result and current_try < MAX_RETRIES - 1 :
current_try + = 1
try :
result = _get_req_session ( ) . request (
method , request_url , params = params , files = files ,
timeout = ( connect_timeout , read_timeout ) , proxies = proxy )
got_result = True
except HTTPError :
logger . debug ( " HTTP Error on {0} method (Try # {1} ) " . format ( method_name , current_try ) )
time . sleep ( RETRY_TIMEOUT )
except ConnectionError :
logger . debug ( " Connection Error on {0} method (Try # {1} ) " . format ( method_name , current_try ) )
time . sleep ( RETRY_TIMEOUT )
except Timeout :
logger . debug ( " Timeout Error on {0} method (Try # {1} ) " . format ( method_name , current_try ) )
time . sleep ( RETRY_TIMEOUT )
if not got_result :
result = _get_req_session ( ) . request (
method , request_url , params = params , files = files ,
timeout = ( connect_timeout , read_timeout ) , proxies = proxy )
else :
result = _get_req_session ( ) . request (
method , request_url , params = params , files = files ,
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 ' ) ) )
2020-08-03 04:39:12 +03:00
json_result = _check_result ( method_name , result )
if json_result :
return json_result [ ' result ' ]
2015-08-19 22:29:17 +03:00
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 )
2020-07-31 01:30:03 +03:00
: raises ApiException : if one of the above listed cases is applicable
2015-08-19 22:29:17 +03:00
: 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
try :
result_json = result . json ( )
except :
2020-08-04 03:34:13 +03:00
if result . status_code != 200 :
raise ApiHTTPException ( method_name , result )
else :
raise ApiInvalidJSONException ( method_name , result )
2020-08-03 04:39:12 +03:00
else :
if not result_json [ ' ok ' ] :
raise ApiTelegramException ( method_name , result , result_json )
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
2021-06-21 18:39:13 +03:00
2021-06-17 21:28:53 +03:00
def log_out ( token ) :
method_url = r ' logOut '
return _make_request ( token , method_url )
2021-06-21 18:39:13 +03:00
2021-06-17 21:28:53 +03:00
def close ( token ) :
method_url = r ' close '
return _make_request ( token , method_url )
2015-09-18 21:53:10 +03:00
2021-06-21 18:39:13 +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
2018-03-25 13:21:55 +03:00
def get_file_url ( token , file_id ) :
2019-08-12 17:09:52 +03:00
if FILE_URL is None :
2019-11-05 17:37:53 +03:00
return " https://api.telegram.org/file/bot {0} / {1} " . format ( token , get_file ( token , file_id ) [ ' file_path ' ] )
2019-08-12 17:09:52 +03:00
else :
2021-07-09 10:42:56 +03:00
# noinspection PyUnresolvedReferences
2019-10-30 16:24:43 +03:00
return FILE_URL . format ( token , get_file ( token , file_id ) [ ' file_path ' ] )
2021-07-09 10:42:56 +03:00
2018-03-25 13:21:55 +03:00
2015-09-18 21:53:10 +03:00
def download_file ( token , file_path ) :
2019-11-05 17:37:53 +03:00
if FILE_URL is None :
url = " https://api.telegram.org/file/bot {0} / {1} " . format ( token , file_path )
else :
2021-07-09 10:42:56 +03:00
# noinspection PyUnresolvedReferences
2019-11-05 17:37:53 +03:00
url = FILE_URL . format ( token , file_path )
2018-04-24 13:48:39 +03:00
result = _get_req_session ( ) . get ( url , proxies = proxy )
2015-09-18 21:53:10 +03:00
if result . status_code != 200 :
2020-07-31 01:10:34 +03:00
raise ApiHTTPException ( ' Download file ' , result )
2015-09-18 21:53:10 +03:00
return result . content
2020-05-16 17:34:56 +03:00
def send_message (
token , chat_id , text ,
disable_web_page_preview = None , reply_to_message_id = None , reply_markup = None ,
2021-06-21 18:39:13 +03:00
parse_mode = None , disable_notification = None , timeout = None ,
entities = None , allow_sending_without_reply = 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 :
2018-08-17 12:49:37 +03:00
: param parse_mode :
: param disable_notification :
2020-05-16 17:34:56 +03:00
: param timeout :
2021-06-21 18:39:13 +03:00
: param entities :
: param allow_sending_without_reply :
2015-06-26 10:46:02 +03:00
: 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 }
2020-05-16 17:34:56 +03:00
if disable_web_page_preview is not None :
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
2020-05-16 17:34:56 +03:00
if disable_notification is not None :
2016-02-27 06:17:35 +03:00
payload [ ' disable_notification ' ] = disable_notification
2018-07-24 00:33:13 +03:00
if timeout :
2021-07-09 10:42:56 +03:00
payload [ ' timeout ' ] = timeout
2021-06-21 18:39:13 +03:00
if entities :
payload [ ' entities ' ] = json . dumps ( types . MessageEntity . to_list_of_dicts ( entities ) )
2021-06-21 20:59:39 +03:00
if allow_sending_without_reply is not None :
2021-06-21 18:39:13 +03:00
payload [ ' allow_sending_without_reply ' ] = allow_sending_without_reply
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
2021-01-09 21:22:49 +03:00
def set_webhook ( token , url = None , certificate = None , max_connections = None , allowed_updates = None , ip_address = None ,
drop_pending_updates = None , timeout = 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
2021-01-09 21:22:49 +03:00
if allowed_updates is not None : # Empty lists should pass
2017-06-22 06:35:13 +03:00
payload [ ' allowed_updates ' ] = json . dumps ( allowed_updates )
2021-01-09 21:22:49 +03:00
if ip_address is not None : # Empty string should pass
2020-12-29 19:24:41 +03:00
payload [ ' ip_address ' ] = ip_address
2021-01-09 21:22:49 +03:00
if drop_pending_updates is not None : # Any bool value should pass
payload [ ' drop_pending_updates ' ] = drop_pending_updates
2021-01-07 00:13:44 +03:00
if timeout :
2021-07-09 10:42:56 +03:00
payload [ ' timeout ' ] = timeout
2015-09-18 21:12:53 +03:00
return _make_request ( token , method_url , params = payload , files = files )
2021-01-07 00:13:44 +03:00
def delete_webhook ( token , drop_pending_updates = None , timeout = None ) :
2016-12-06 06:52:16 +03:00
method_url = r ' deleteWebhook '
2020-12-29 19:24:41 +03:00
payload = { }
2021-01-09 21:22:49 +03:00
if drop_pending_updates is not None : # Any bool value should pass
2020-12-29 19:24:41 +03:00
payload [ ' drop_pending_updates ' ] = drop_pending_updates
2021-01-07 00:13:44 +03:00
if timeout :
2021-07-09 10:42:56 +03:00
payload [ ' timeout ' ] = timeout
2020-12-29 19:24:41 +03:00
return _make_request ( token , method_url , params = payload )
2016-12-06 06:52:16 +03:00
2021-01-07 00:13:44 +03:00
def get_webhook_info ( token , timeout = None ) :
2016-10-20 10:52:38 +03:00
method_url = r ' getWebhookInfo '
payload = { }
2021-01-07 00:13:44 +03:00
if timeout :
2021-07-09 10:42:56 +03:00
payload [ ' timeout ' ] = timeout
2016-10-20 10:52:38 +03:00
return _make_request ( token , method_url , params = payload )
2020-11-07 14:02:11 +03:00
def get_updates ( token , offset = None , limit = None , timeout = None , allowed_updates = None , long_polling_timeout = 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 :
2021-07-09 10:42:56 +03:00
payload [ ' timeout ' ] = timeout
payload [ ' long_polling_timeout ' ] = long_polling_timeout if long_polling_timeout else LONG_POLLING_TIMEOUT
2020-11-11 00:32:34 +03:00
if allowed_updates is not None : # Empty lists should pass
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 )
2021-06-28 10:31:06 +03:00
def get_chat_member_count ( token , chat_id ) :
method_url = r ' getChatMemberCount '
payload = { ' chat_id ' : chat_id }
return _make_request ( token , method_url , params = payload )
2021-06-21 18:39:13 +03:00
def set_sticker_set_thumb ( token , name , user_id , thumb ) :
method_url = r ' setStickerSetThumb '
payload = { ' name ' : name , ' user_id ' : user_id }
files = { }
if thumb :
if not isinstance ( thumb , str ) :
files [ ' thumb ' ] = thumb
else :
payload [ ' thumb ' ] = thumb
return _make_request ( token , method_url , params = payload , files = files or None )
2017-10-22 19:50:51 +03:00
def set_chat_sticker_set ( token , chat_id , sticker_set_name ) :
method_url = r ' setChatStickerSet '
payload = { ' chat_id ' : chat_id , ' sticker_set_name ' : sticker_set_name }
return _make_request ( token , method_url , params = payload )
def delete_chat_sticker_set ( token , chat_id ) :
method_url = r ' deleteChatStickerSet '
payload = { ' chat_id ' : chat_id }
return _make_request ( token , method_url , params = payload )
2016-06-07 14:00:44 +03:00
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 )
2020-05-16 17:34:56 +03:00
def forward_message (
token , chat_id , from_chat_id , message_id ,
disable_notification = None , timeout = 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 }
2020-05-16 17:34:56 +03:00
if disable_notification is not None :
2016-02-27 06:17:35 +03:00
payload [ ' disable_notification ' ] = disable_notification
2020-05-16 17:34:56 +03:00
if timeout :
2021-07-09 10:42:56 +03:00
payload [ ' timeout ' ] = timeout
2015-07-01 23:16:13 +03:00
return _make_request ( token , method_url , params = payload )
2015-06-26 20:53:07 +03:00
2021-01-11 02:20:17 +03:00
def copy_message ( token , chat_id , from_chat_id , message_id , caption = None , parse_mode = None , caption_entities = None ,
2021-01-19 01:27:39 +03:00
disable_notification = None , reply_to_message_id = None , allow_sending_without_reply = None ,
reply_markup = None , timeout = None ) :
2021-01-11 02:20:17 +03:00
method_url = r ' copyMessage '
payload = { ' chat_id ' : chat_id , ' from_chat_id ' : from_chat_id , ' message_id ' : message_id }
if caption is not None :
payload [ ' caption ' ] = caption
2021-01-19 01:27:39 +03:00
if parse_mode :
2021-01-11 02:20:17 +03:00
payload [ ' parse_mode ' ] = parse_mode
if caption_entities is not None :
2021-01-12 10:47:53 +03:00
payload [ ' caption_entities ' ] = _convert_entites ( caption_entities )
2021-01-19 01:27:39 +03:00
if disable_notification is not None :
payload [ ' disable_notification ' ] = disable_notification
if reply_to_message_id :
2021-01-11 02:20:17 +03:00
payload [ ' reply_to_message_id ' ] = reply_to_message_id
if reply_markup is not None :
2021-01-12 10:47:53 +03:00
payload [ ' reply_markup ' ] = _convert_markup ( reply_markup )
2021-01-11 02:20:17 +03:00
if allow_sending_without_reply is not None :
payload [ ' allow_sending_without_reply ' ] = allow_sending_without_reply
if timeout :
2021-07-09 10:42:56 +03:00
payload [ ' timeout ' ] = timeout
2015-07-01 23:16:13 +03:00
return _make_request ( token , method_url , params = payload )
2015-06-26 20:53:07 +03:00
2020-05-16 17:34:56 +03:00
def send_dice (
token , chat_id ,
emoji = None , disable_notification = None , reply_to_message_id = None ,
2021-06-21 18:39:13 +03:00
reply_markup = None , timeout = None , allow_sending_without_reply = None ) :
2020-04-15 08:10:05 +03:00
method_url = r ' sendDice '
payload = { ' chat_id ' : chat_id }
2020-04-27 08:30:05 +03:00
if emoji :
payload [ ' emoji ' ] = emoji
2020-05-16 17:34:56 +03:00
if disable_notification is not None :
2020-04-15 08:10:05 +03:00
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 )
2020-05-16 17:34:56 +03:00
if timeout :
2021-07-09 10:42:56 +03:00
payload [ ' timeout ' ] = timeout
2021-06-21 20:59:39 +03:00
if allow_sending_without_reply is not None :
2021-06-21 18:39:13 +03:00
payload [ ' allow_sending_without_reply ' ] = allow_sending_without_reply
2020-04-15 08:10:05 +03:00
return _make_request ( token , method_url , params = payload )
2020-05-16 17:34:56 +03:00
def send_photo (
token , chat_id , photo ,
caption = None , reply_to_message_id = None , reply_markup = None ,
2021-06-21 18:39:13 +03:00
parse_mode = None , disable_notification = None , timeout = None ,
caption_entities = None , allow_sending_without_reply = 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
2020-07-31 08:45:58 +03:00
if util . is_string ( photo ) :
2015-07-14 08:24:32 +03:00
payload [ ' photo ' ] = photo
2020-07-31 08:45:58 +03:00
elif util . is_pil_image ( photo ) :
files = { ' photo ' : util . pil_image_to_file ( photo ) }
else :
files = { ' 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 )
2018-02-14 23:27:55 +03:00
if parse_mode :
payload [ ' parse_mode ' ] = parse_mode
2020-05-16 17:34:56 +03:00
if disable_notification is not None :
2016-02-27 06:17:35 +03:00
payload [ ' disable_notification ' ] = disable_notification
2020-05-16 17:34:56 +03:00
if timeout :
2021-07-09 10:42:56 +03:00
payload [ ' timeout ' ] = timeout
2021-06-21 18:39:13 +03:00
if caption_entities :
payload [ ' caption_entities ' ] = json . dumps ( types . MessageEntity . to_list_of_dicts ( caption_entities ) )
2021-06-21 20:59:39 +03:00
if allow_sending_without_reply is not None :
2021-06-21 18:39:13 +03:00
payload [ ' allow_sending_without_reply ' ] = allow_sending_without_reply
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
2020-05-16 17:34:56 +03:00
def send_media_group (
token , chat_id , media ,
disable_notification = None , reply_to_message_id = None ,
2021-06-21 18:39:13 +03:00
timeout = None , allow_sending_without_reply = None ) :
2017-11-29 08:45:25 +03:00
method_url = r ' sendMediaGroup '
2020-07-21 01:20:01 +03:00
media_json , files = convert_input_media_array ( media )
2017-11-29 08:45:25 +03:00
payload = { ' chat_id ' : chat_id , ' media ' : media_json }
2020-05-16 17:34:56 +03:00
if disable_notification is not None :
2017-11-29 08:45:25 +03:00
payload [ ' disable_notification ' ] = disable_notification
if reply_to_message_id :
payload [ ' reply_to_message_id ' ] = reply_to_message_id
2020-05-16 17:34:56 +03:00
if timeout :
2021-07-09 10:42:56 +03:00
payload [ ' timeout ' ] = timeout
2021-06-21 20:59:39 +03:00
if allow_sending_without_reply is not None :
2021-06-21 18:39:13 +03:00
payload [ ' allow_sending_without_reply ' ] = allow_sending_without_reply
2020-05-16 17:34:56 +03:00
return _make_request (
token , method_url , params = payload ,
method = ' post ' if files else ' get ' ,
files = files if files else None )
2017-11-29 08:45:25 +03:00
2020-05-16 17:34:56 +03:00
def send_location (
token , chat_id , latitude , longitude ,
2021-06-21 18:39:13 +03:00
live_period = None , reply_to_message_id = None ,
reply_markup = None , disable_notification = None ,
timeout = None , horizontal_accuracy = None , heading = None ,
proximity_alert_radius = None , allow_sending_without_reply = None ) :
2015-06-27 17:11:18 +03:00
method_url = r ' sendLocation '
payload = { ' chat_id ' : chat_id , ' latitude ' : latitude , ' longitude ' : longitude }
2017-10-22 19:50:51 +03:00
if live_period :
2017-12-05 00:21:05 +03:00
payload [ ' live_period ' ] = live_period
2021-06-21 18:39:13 +03:00
if horizontal_accuracy :
payload [ ' horizontal_accuracy ' ] = horizontal_accuracy
if heading :
payload [ ' heading ' ] = heading
if proximity_alert_radius :
payload [ ' proximity_alert_radius ' ] = proximity_alert_radius
2015-06-27 17:11:18 +03:00
if reply_to_message_id :
payload [ ' reply_to_message_id ' ] = reply_to_message_id
2021-06-21 20:59:39 +03:00
if allow_sending_without_reply is not None :
2021-06-21 18:39:13 +03:00
payload [ ' allow_sending_without_reply ' ] = allow_sending_without_reply
2015-06-27 17:11:18 +03:00
if reply_markup :
2015-07-02 14:43:49 +03:00
payload [ ' reply_markup ' ] = _convert_markup ( reply_markup )
2020-05-16 17:34:56 +03:00
if disable_notification is not None :
2016-02-27 06:17:35 +03:00
payload [ ' disable_notification ' ] = disable_notification
2020-05-16 17:34:56 +03:00
if timeout :
2021-07-09 10:42:56 +03:00
payload [ ' timeout ' ] = timeout
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
2021-06-21 18:39:13 +03:00
def edit_message_live_location (
token , latitude , longitude , chat_id = None , message_id = None ,
inline_message_id = None , reply_markup = None , timeout = None ,
horizontal_accuracy = None , heading = None , proximity_alert_radius = None ) :
2017-10-22 19:50:51 +03:00
method_url = r ' editMessageLiveLocation '
payload = { ' latitude ' : latitude , ' longitude ' : longitude }
if chat_id :
payload [ ' chat_id ' ] = chat_id
if message_id :
payload [ ' message_id ' ] = message_id
2021-06-21 18:39:13 +03:00
if horizontal_accuracy :
payload [ ' horizontal_accuracy ' ] = horizontal_accuracy
if heading :
payload [ ' heading ' ] = heading
if proximity_alert_radius :
payload [ ' proximity_alert_radius ' ] = proximity_alert_radius
2017-10-22 19:50:51 +03:00
if inline_message_id :
payload [ ' inline_message_id ' ] = inline_message_id
if reply_markup :
payload [ ' reply_markup ' ] = _convert_markup ( reply_markup )
2020-05-16 17:34:56 +03:00
if timeout :
2021-07-09 10:42:56 +03:00
payload [ ' timeout ' ] = timeout
2017-10-22 19:50:51 +03:00
return _make_request ( token , method_url , params = payload )
2020-05-16 17:34:56 +03:00
def stop_message_live_location (
token , chat_id = None , message_id = None ,
inline_message_id = None , reply_markup = None , timeout = None ) :
2017-10-22 19:50:51 +03:00
method_url = r ' stopMessageLiveLocation '
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 )
2020-05-16 17:34:56 +03:00
if timeout :
2021-07-09 10:42:56 +03:00
payload [ ' timeout ' ] = timeout
2017-10-22 19:50:51 +03:00
return _make_request ( token , method_url , params = payload )
2020-05-16 17:34:56 +03:00
def send_venue (
token , chat_id , latitude , longitude , title , address ,
2020-08-25 18:18:51 +03:00
foursquare_id = None , foursquare_type = None , disable_notification = None ,
2021-06-21 18:39:13 +03:00
reply_to_message_id = None , reply_markup = None , timeout = None ,
allow_sending_without_reply = None , google_place_id = None ,
google_place_type = None ) :
2016-04-14 08:55:28 +03:00
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
2020-08-25 18:18:51 +03:00
if foursquare_type :
payload [ ' foursquare_type ' ] = foursquare_type
2020-05-16 17:34:56 +03:00
if disable_notification is not None :
2016-04-14 08:55:28 +03:00
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 )
2020-05-16 17:34:56 +03:00
if timeout :
2021-07-09 10:42:56 +03:00
payload [ ' timeout ' ] = timeout
2021-06-21 20:59:39 +03:00
if allow_sending_without_reply is not None :
2021-06-21 18:39:13 +03:00
payload [ ' allow_sending_without_reply ' ] = allow_sending_without_reply
if google_place_id :
payload [ ' google_place_id ' ] = google_place_id
if google_place_type :
payload [ ' google_place_type ' ] = google_place_type
2016-04-14 08:55:28 +03:00
return _make_request ( token , method_url , params = payload )
2016-04-16 10:07:52 +03:00
2020-05-16 17:34:56 +03:00
def send_contact (
2020-08-25 18:18:51 +03:00
token , chat_id , phone_number , first_name , last_name = None , vcard = None ,
2021-06-21 18:39:13 +03:00
disable_notification = None , reply_to_message_id = None , reply_markup = None , timeout = None ,
allow_sending_without_reply = None ) :
2016-04-16 10:07:52 +03:00
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
2020-08-25 18:18:51 +03:00
if vcard :
payload [ ' vcard ' ] = vcard
2020-05-16 17:34:56 +03:00
if disable_notification is not None :
2016-04-16 10:07:52 +03:00
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 )
2020-05-16 17:34:56 +03:00
if timeout :
2021-07-09 10:42:56 +03:00
payload [ ' timeout ' ] = timeout
2021-06-21 20:59:39 +03:00
if allow_sending_without_reply is not None :
2021-06-21 18:39:13 +03:00
payload [ ' allow_sending_without_reply ' ] = allow_sending_without_reply
2016-04-16 10:07:52 +03:00
return _make_request ( token , method_url , params = payload )
2016-04-14 08:55:28 +03:00
2020-05-16 17:34:56 +03:00
def send_chat_action ( token , chat_id , action , timeout = None ) :
2015-06-28 12:56:32 +03:00
method_url = r ' sendChatAction '
payload = { ' chat_id ' : chat_id , ' action ' : action }
2020-05-16 17:34:56 +03:00
if timeout :
2021-07-09 10:42:56 +03:00
payload [ ' timeout ' ] = timeout
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 ,
2021-06-21 18:39:13 +03:00
parse_mode = None , supports_streaming = None , disable_notification = None , timeout = None ,
thumb = None , width = None , height = None , caption_entities = None , allow_sending_without_reply = 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 )
2018-02-14 23:27:55 +03:00
if parse_mode :
payload [ ' parse_mode ' ] = parse_mode
2020-05-16 17:34:56 +03:00
if supports_streaming is not None :
2018-02-14 23:27:55 +03:00
payload [ ' supports_streaming ' ] = supports_streaming
2020-05-16 17:34:56 +03:00
if disable_notification is not None :
2016-02-27 06:17:35 +03:00
payload [ ' disable_notification ' ] = disable_notification
2016-05-22 19:35:20 +03:00
if timeout :
2021-07-09 10:42:56 +03:00
payload [ ' timeout ' ] = timeout
2020-06-23 21:17:21 +03:00
if thumb :
if not util . is_string ( thumb ) :
2020-08-22 17:11:52 +03:00
if files :
files [ ' thumb ' ] = thumb
else :
files = { ' thumb ' : thumb }
2020-06-23 21:17:21 +03:00
else :
payload [ ' thumb ' ] = thumb
2020-07-02 17:46:41 +03:00
if width :
payload [ ' width ' ] = width
if height :
payload [ ' height ' ] = height
2021-06-21 18:39:13 +03:00
if caption_entities :
payload [ ' caption_entities ' ] = json . dumps ( types . MessageEntity . to_list_of_dicts ( caption_entities ) )
2021-06-21 20:59:39 +03:00
if allow_sending_without_reply is not None :
2021-06-21 18:39:13 +03:00
payload [ ' allow_sending_without_reply ' ] = allow_sending_without_reply
2015-08-01 05:12:15 +03:00
return _make_request ( token , method_url , params = payload , files = files , method = ' post ' )
2021-06-21 18:39:13 +03:00
def send_animation (
token , chat_id , data , duration = None , caption = None , reply_to_message_id = None , reply_markup = None ,
parse_mode = None , disable_notification = None , timeout = None , thumb = None , caption_entities = None ,
allow_sending_without_reply = None ) :
2019-02-15 21:46:18 +03:00
method_url = r ' sendAnimation '
payload = { ' chat_id ' : chat_id }
files = None
if not util . is_string ( data ) :
files = { ' animation ' : data }
else :
payload [ ' animation ' ] = 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 )
if parse_mode :
payload [ ' parse_mode ' ] = parse_mode
2020-05-16 17:34:56 +03:00
if disable_notification is not None :
2019-02-15 21:46:18 +03:00
payload [ ' disable_notification ' ] = disable_notification
if timeout :
2021-07-09 10:42:56 +03:00
payload [ ' timeout ' ] = timeout
2020-08-21 11:09:43 +03:00
if thumb :
2020-08-21 14:09:38 +03:00
if not util . is_string ( thumb ) :
2020-08-22 17:11:52 +03:00
if files :
files [ ' thumb ' ] = thumb
else :
files = { ' thumb ' : thumb }
2020-08-21 14:09:38 +03:00
else :
payload [ ' thumb ' ] = thumb
2021-06-21 18:39:13 +03:00
if caption_entities :
payload [ ' caption_entities ' ] = json . dumps ( types . MessageEntity . to_list_of_dicts ( caption_entities ) )
2021-06-21 20:59:39 +03:00
if allow_sending_without_reply is not None :
2021-06-21 18:39:13 +03:00
payload [ ' allow_sending_without_reply ' ] = allow_sending_without_reply
2019-02-15 21:46:18 +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 ,
2021-06-21 18:39:13 +03:00
parse_mode = None , disable_notification = None , timeout = None , caption_entities = None ,
allow_sending_without_reply = 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 )
2018-02-14 23:27:55 +03:00
if parse_mode :
payload [ ' parse_mode ' ] = parse_mode
2020-05-16 17:34:56 +03:00
if disable_notification is not None :
2016-02-27 06:17:35 +03:00
payload [ ' disable_notification ' ] = disable_notification
2016-05-22 19:35:20 +03:00
if timeout :
2021-07-09 10:42:56 +03:00
payload [ ' timeout ' ] = timeout
2021-06-21 18:39:13 +03:00
if caption_entities :
payload [ ' caption_entities ' ] = json . dumps ( types . MessageEntity . to_list_of_dicts ( caption_entities ) )
2021-06-21 20:59:39 +03:00
if allow_sending_without_reply is not None :
2021-06-21 18:39:13 +03:00
payload [ ' allow_sending_without_reply ' ] = allow_sending_without_reply
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 ,
2021-06-21 18:39:13 +03:00
disable_notification = None , timeout = None , thumb = None , allow_sending_without_reply = None ) :
2017-05-19 17:19:15 +03:00
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
2020-08-21 11:09:43 +03:00
if length and ( str ( length ) . isdigit ( ) and int ( length ) < = 639 ) :
2017-05-19 17:19:15 +03:00
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 )
2020-05-16 17:34:56 +03:00
if disable_notification is not None :
2017-05-19 17:19:15 +03:00
payload [ ' disable_notification ' ] = disable_notification
if timeout :
2021-07-09 10:42:56 +03:00
payload [ ' timeout ' ] = timeout
2020-08-21 11:09:43 +03:00
if thumb :
2020-08-21 14:09:38 +03:00
if not util . is_string ( thumb ) :
2020-08-22 17:11:52 +03:00
if files :
files [ ' thumb ' ] = thumb
else :
files = { ' thumb ' : thumb }
2020-08-21 14:09:38 +03:00
else :
payload [ ' thumb ' ] = thumb
2021-06-21 20:59:39 +03:00
if allow_sending_without_reply is not None :
2021-06-21 18:39:13 +03:00
payload [ ' allow_sending_without_reply ' ] = allow_sending_without_reply
2017-05-19 17:19: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_audio ( token , chat_id , audio , caption = None , duration = None , performer = None , title = None , reply_to_message_id = None ,
2021-06-21 18:39:13 +03:00
reply_markup = None , parse_mode = None , disable_notification = None , timeout = None , thumb = None ,
caption_entities = None , allow_sending_without_reply = 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 )
2018-02-14 23:27:55 +03:00
if parse_mode :
payload [ ' parse_mode ' ] = parse_mode
2020-05-16 17:34:56 +03:00
if disable_notification is not None :
2016-02-27 06:17:35 +03:00
payload [ ' disable_notification ' ] = disable_notification
2016-05-22 19:35:20 +03:00
if timeout :
2021-07-09 10:42:56 +03:00
payload [ ' timeout ' ] = timeout
2020-06-23 21:10:12 +03:00
if thumb :
if not util . is_string ( thumb ) :
2020-08-22 17:11:52 +03:00
if files :
files [ ' thumb ' ] = thumb
else :
files = { ' thumb ' : thumb }
2020-06-23 21:10:12 +03:00
else :
payload [ ' thumb ' ] = thumb
2021-06-21 18:39:13 +03:00
if caption_entities :
payload [ ' caption_entities ' ] = json . dumps ( types . MessageEntity . to_list_of_dicts ( caption_entities ) )
2021-06-21 20:59:39 +03:00
if allow_sending_without_reply is not None :
2021-06-21 18:39:13 +03:00
payload [ ' allow_sending_without_reply ' ] = allow_sending_without_reply
2015-08-19 13:08:01 +03:00
return _make_request ( token , method_url , params = payload , files = files , method = ' post ' )
2018-02-16 18:29:29 +03:00
def send_data ( token , chat_id , data , data_type , reply_to_message_id = None , reply_markup = None , parse_mode = None ,
2021-06-21 18:39:13 +03:00
disable_notification = None , timeout = None , caption = None , thumb = None , caption_entities = None ,
2021-06-29 13:30:01 +03:00
allow_sending_without_reply = None , disable_content_type_detection = None , visible_file_name = 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 ) :
2021-06-27 11:37:27 +03:00
file_data = data
2021-06-29 13:30:01 +03:00
if visible_file_name :
file_data = ( visible_file_name , data )
2021-06-27 11:37:27 +03:00
files = { data_type : file_data }
2015-07-14 08:24:32 +03:00
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 )
2018-02-14 23:27:55 +03:00
if parse_mode and data_type == ' document ' :
payload [ ' parse_mode ' ] = parse_mode
2020-05-16 17:34:56 +03:00
if disable_notification is not None :
2016-02-27 06:17:35 +03:00
payload [ ' disable_notification ' ] = disable_notification
2016-05-22 19:35:20 +03:00
if timeout :
2021-07-09 10:42:56 +03:00
payload [ ' timeout ' ] = timeout
2016-06-02 08:15:22 +03:00
if caption :
payload [ ' caption ' ] = caption
2020-08-21 11:09:43 +03:00
if thumb :
2020-08-21 14:09:38 +03:00
if not util . is_string ( thumb ) :
2020-08-22 17:11:52 +03:00
if files :
files [ ' thumb ' ] = thumb
else :
files = { ' thumb ' : thumb }
2020-08-21 14:09:38 +03:00
else :
payload [ ' thumb ' ] = thumb
2021-06-21 18:39:13 +03:00
if caption_entities :
payload [ ' caption_entities ' ] = json . dumps ( types . MessageEntity . to_list_of_dicts ( caption_entities ) )
2021-06-21 20:59:39 +03:00
if allow_sending_without_reply is not None :
2021-06-21 18:39:13 +03:00
payload [ ' allow_sending_without_reply ' ] = allow_sending_without_reply
2021-06-22 16:57:34 +03:00
if method_url == ' sendDocument ' and disable_content_type_detection is not None :
payload [ ' disable_content_type_detection ' ] = disable_content_type_detection
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
2021-06-28 10:31:06 +03:00
def ban_chat_member ( token , chat_id , user_id , until_date = None , revoke_messages = None ) :
method_url = ' banChatMember '
payload = { ' chat_id ' : chat_id , ' user_id ' : user_id }
if isinstance ( until_date , datetime ) :
payload [ ' until_date ' ] = until_date . timestamp ( )
else :
payload [ ' until_date ' ] = until_date
if revoke_messages is not None :
payload [ ' revoke_messages ' ] = revoke_messages
return _make_request ( token , method_url , params = payload , method = ' post ' )
2020-11-18 02:22:52 +03:00
def unban_chat_member ( token , chat_id , user_id , only_if_banned ) :
2016-04-14 09:48:26 +03:00
method_url = ' unbanChatMember '
payload = { ' chat_id ' : chat_id , ' user_id ' : user_id }
2020-12-29 19:24:41 +03:00
if only_if_banned is not None : # None / True / False
2020-11-18 02:22:52 +03:00
payload [ ' only_if_banned ' ] = only_if_banned
2016-04-14 09:48:26 +03:00
return _make_request ( token , method_url , params = payload , method = ' post ' )
2020-05-16 17:34:56 +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_polls = None , can_send_other_messages = None ,
can_add_web_page_previews = None , can_change_info = None ,
can_invite_users = None , can_pin_messages = None ) :
2017-06-30 19:47:09 +03:00
method_url = ' restrictChatMember '
2020-12-22 21:38:38 +03:00
permissions = { }
2020-05-16 17:34:56 +03:00
if can_send_messages is not None :
2020-12-22 21:38:38 +03:00
permissions [ ' can_send_messages ' ] = can_send_messages
2020-05-16 17:34:56 +03:00
if can_send_media_messages is not None :
2020-12-22 21:38:38 +03:00
permissions [ ' can_send_media_messages ' ] = can_send_media_messages
2020-05-16 17:34:56 +03:00
if can_send_polls is not None :
2020-12-22 21:38:38 +03:00
permissions [ ' can_send_polls ' ] = can_send_polls
2020-05-16 17:34:56 +03:00
if can_send_other_messages is not None :
2020-12-22 21:38:38 +03:00
permissions [ ' can_send_other_messages ' ] = can_send_other_messages
2020-05-16 17:34:56 +03:00
if can_add_web_page_previews is not None :
2020-12-22 21:38:38 +03:00
permissions [ ' can_add_web_page_previews ' ] = can_add_web_page_previews
2020-05-16 17:34:56 +03:00
if can_change_info is not None :
2020-12-22 21:38:38 +03:00
permissions [ ' can_change_info ' ] = can_change_info
2020-05-16 17:34:56 +03:00
if can_invite_users is not None :
2020-12-22 21:38:38 +03:00
permissions [ ' can_invite_users ' ] = can_invite_users
2020-05-16 17:34:56 +03:00
if can_pin_messages is not None :
2020-12-22 21:38:38 +03:00
permissions [ ' can_pin_messages ' ] = can_pin_messages
permissions_json = json . dumps ( permissions )
payload = { ' chat_id ' : chat_id , ' user_id ' : user_id , ' permissions ' : permissions_json }
2021-01-14 15:45:47 +03:00
if until_date is not None :
2021-01-16 23:50:25 +03:00
if isinstance ( until_date , datetime ) :
2021-01-14 15:45:47 +03:00
payload [ ' until_date ' ] = until_date . timestamp ( )
else :
payload [ ' until_date ' ] = until_date
2017-06-30 19:47:09 +03:00
return _make_request ( token , method_url , params = payload , method = ' post ' )
2020-05-16 17:34:56 +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 ,
2021-06-21 18:39:13 +03:00
can_restrict_members = None , can_pin_messages = None , can_promote_members = None ,
is_anonymous = None , can_manage_chat = None , can_manage_voice_chats = 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 }
2020-05-16 17:34:56 +03:00
if can_change_info is not None :
2017-07-02 16:08:36 +03:00
payload [ ' can_change_info ' ] = can_change_info
2020-05-16 17:34:56 +03:00
if can_post_messages is not None :
2017-07-02 16:08:36 +03:00
payload [ ' can_post_messages ' ] = can_post_messages
2020-05-16 17:34:56 +03:00
if can_edit_messages is not None :
2017-07-02 16:08:36 +03:00
payload [ ' can_edit_messages ' ] = can_edit_messages
2020-05-16 17:34:56 +03:00
if can_delete_messages is not None :
2017-07-02 16:08:36 +03:00
payload [ ' can_delete_messages ' ] = can_delete_messages
2020-05-16 17:34:56 +03:00
if can_invite_users is not None :
2017-07-02 16:08:36 +03:00
payload [ ' can_invite_users ' ] = can_invite_users
2020-05-16 17:34:56 +03:00
if can_restrict_members is not None :
2017-07-02 16:08:36 +03:00
payload [ ' can_restrict_members ' ] = can_restrict_members
2020-05-16 17:34:56 +03:00
if can_pin_messages is not None :
2017-07-02 16:08:36 +03:00
payload [ ' can_pin_messages ' ] = can_pin_messages
2020-05-16 17:34:56 +03:00
if can_promote_members is not None :
2017-07-02 16:08:36 +03:00
payload [ ' can_promote_members ' ] = can_promote_members
2021-06-21 18:39:13 +03:00
if is_anonymous is not None :
payload [ ' is_anonymous ' ] = is_anonymous
if can_manage_chat is not None :
payload [ ' can_manage_chat ' ] = can_manage_chat
if can_manage_voice_chats is not None :
payload [ ' can_manage_voice_chats ' ] = can_manage_voice_chats
2017-06-30 19:47:09 +03:00
return _make_request ( token , method_url , params = payload , method = ' post ' )
2020-05-09 23:23:08 +03:00
def set_chat_administrator_custom_title ( token , chat_id , user_id , custom_title ) :
method_url = ' setChatAdministratorCustomTitle '
payload = {
2020-05-20 11:57:41 +03:00
' chat_id ' : chat_id , ' user_id ' : user_id , ' custom_title ' : custom_title
}
2020-05-09 23:23:08 +03:00
return _make_request ( token , method_url , params = payload , method = ' post ' )
2020-05-11 16:38:09 +03:00
def set_chat_permissions ( token , chat_id , permissions ) :
method_url = ' setChatPermissions '
payload = {
' chat_id ' : chat_id ,
2020-05-20 11:57:41 +03:00
' permissions ' : permissions . to_json ( )
}
2020-05-11 16:38:09 +03:00
return _make_request ( token , method_url , params = payload , method = ' post ' )
2021-05-19 02:24:07 +03:00
def create_chat_invite_link ( token , chat_id , expire_date , member_limit ) :
method_url = ' createChatInviteLink '
payload = {
' chat_id ' : chat_id
}
if expire_date is not None :
2021-08-22 22:16:03 +03:00
if isinstance ( expire_date , datetime ) :
payload [ ' expire_date ' ] = expire_date . timestamp ( )
2021-08-18 23:27:28 +03:00
else :
payload [ ' expire_date ' ] = expire_date
if member_limit :
2021-05-19 02:24:07 +03:00
payload [ ' member_limit ' ] = member_limit
return _make_request ( token , method_url , params = payload , method = ' post ' )
def edit_chat_invite_link ( token , chat_id , invite_link , expire_date , member_limit ) :
method_url = ' editChatInviteLink '
payload = {
' chat_id ' : chat_id ,
' invite_link ' : invite_link
}
if expire_date is not None :
2021-08-22 22:16:03 +03:00
if isinstance ( expire_date , datetime ) :
payload [ ' expire_date ' ] = expire_date . timestamp ( )
2021-08-18 23:27:28 +03:00
else :
payload [ ' expire_date ' ] = expire_date
2021-05-19 02:24:07 +03:00
if member_limit is not None :
payload [ ' member_limit ' ] = member_limit
return _make_request ( token , method_url , params = payload , method = ' post ' )
def revoke_chat_invite_link ( token , chat_id , invite_link ) :
method_url = ' revokeChatInviteLink '
payload = {
' chat_id ' : chat_id ,
' invite_link ' : invite_link
}
return _make_request ( token , method_url , params = payload , method = ' post ' )
2017-06-30 19:47:09 +03:00
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
2020-07-31 08:45:58 +03:00
if util . is_string ( photo ) :
2017-06-30 19:47:09 +03:00
payload [ ' photo ' ] = photo
2020-07-31 08:45:58 +03:00
elif util . is_pil_image ( photo ) :
files = { ' photo ' : util . pil_image_to_file ( photo ) }
else :
files = { ' photo ' : photo }
2017-06-30 19:47:09 +03:00
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 ' )
2021-06-28 10:31:06 +03:00
def get_my_commands ( token , scope = None , language_code = None ) :
2021-06-26 14:36:14 +03:00
method_url = r ' getMyCommands '
payload = { }
2021-06-28 10:31:06 +03:00
if scope :
2021-06-26 14:36:14 +03:00
payload [ ' scope ' ] = scope . to_json ( )
2021-06-28 10:31:06 +03:00
if language_code :
2021-06-26 14:36:14 +03:00
payload [ ' language_code ' ] = language_code
2021-06-28 10:31:06 +03:00
return _make_request ( token , method_url , params = payload )
2021-06-26 14:36:14 +03:00
2021-06-28 10:31:06 +03:00
def set_my_commands ( token , commands , scope = None , language_code = None ) :
2020-05-08 21:06:39 +03:00
method_url = r ' setMyCommands '
payload = { ' commands ' : _convert_list_json_serializable ( commands ) }
2021-06-28 10:31:06 +03:00
if scope :
2021-06-26 14:36:14 +03:00
payload [ ' scope ' ] = scope . to_json ( )
2021-06-28 10:31:06 +03:00
if language_code :
2021-06-26 14:36:14 +03:00
payload [ ' language_code ' ] = language_code
return _make_request ( token , method_url , params = payload , method = ' post ' )
2021-06-28 10:31:06 +03:00
def delete_my_commands ( token , scope = None , language_code = None ) :
2021-06-26 14:36:14 +03:00
method_url = r ' deleteMyCommands '
payload = { }
2021-06-28 10:31:06 +03:00
if scope :
2021-06-26 14:36:14 +03:00
payload [ ' scope ' ] = scope . to_json ( )
2021-06-28 10:31:06 +03:00
if language_code :
2021-06-26 14:36:14 +03:00
payload [ ' language_code ' ] = language_code
2020-05-08 21:06:39 +03:00
return _make_request ( token , method_url , params = payload , method = ' post ' )
2017-06-30 19:47:09 +03:00
def set_chat_description ( token , chat_id , description ) :
method_url = ' setChatDescription '
2020-12-29 19:24:41 +03:00
payload = { ' chat_id ' : chat_id }
if description is not None : # Allow empty strings
payload [ ' description ' ] = description
2017-06-30 19:47:09 +03:00
return _make_request ( token , method_url , params = payload , method = ' post ' )
2020-05-16 17:34:56 +03:00
def pin_chat_message ( token , chat_id , message_id , disable_notification = None ) :
2017-06-30 19:47:09 +03:00
method_url = ' pinChatMessage '
2020-05-16 17:34:56 +03:00
payload = { ' chat_id ' : chat_id , ' message_id ' : message_id }
if disable_notification is not None :
payload [ ' disable_notification ' ] = disable_notification
2017-06-30 19:47:09 +03:00
return _make_request ( token , method_url , params = payload , method = ' post ' )
2020-11-29 15:33:39 +03:00
def unpin_chat_message ( token , chat_id , message_id ) :
2017-06-30 19:47:09 +03:00
method_url = ' unpinChatMessage '
2020-11-29 15:33:39 +03:00
payload = { ' chat_id ' : chat_id }
if message_id :
payload [ ' message_id ' ] = message_id
2020-11-29 14:47:53 +03:00
return _make_request ( token , method_url , params = payload , method = ' post ' )
def unpin_all_chat_messages ( token , chat_id ) :
method_url = ' unpinAllChatMessages '
2017-06-30 19:47:09 +03:00
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 ,
2021-08-18 18:47:38 +03:00
entities = None , disable_web_page_preview = None , reply_markup = None ) :
2016-04-14 10:03:07 +03:00
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
2021-08-18 18:47:38 +03:00
if entities :
payload [ ' entities ' ] = json . dumps ( types . MessageEntity . to_list_of_dicts ( entities ) )
2020-05-16 17:34:56 +03:00
if disable_web_page_preview is not None :
2016-04-14 10:03:07 +03:00
payload [ ' disable_web_page_preview ' ] = disable_web_page_preview
if reply_markup :
payload [ ' reply_markup ' ] = _convert_markup ( reply_markup )
2019-02-23 17:15:20 +03:00
return _make_request ( token , method_url , params = payload , method = ' post ' )
2016-04-14 10:03:07 +03:00
2018-02-16 17:19:35 +03:00
def edit_message_caption ( token , caption , chat_id = None , message_id = None , inline_message_id = None ,
2021-07-28 21:06:31 +03:00
parse_mode = None , caption_entities = None , reply_markup = None ) :
2016-04-14 10:17:53 +03:00
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
2018-02-16 17:19:35 +03:00
if parse_mode :
payload [ ' parse_mode ' ] = parse_mode
2021-07-28 21:06:31 +03:00
if caption_entities :
2021-07-30 17:15:37 +03:00
payload [ ' caption_entities ' ] = json . dumps ( types . MessageEntity . to_list_of_dicts ( caption_entities ) )
2016-04-14 10:17:53 +03:00
if reply_markup :
payload [ ' reply_markup ' ] = _convert_markup ( reply_markup )
2019-02-23 17:15:20 +03:00
return _make_request ( token , method_url , params = payload , method = ' post ' )
2016-04-14 10:17:53 +03:00
2018-08-09 19:10:01 +03:00
def edit_message_media ( token , media , chat_id = None , message_id = None , inline_message_id = None , reply_markup = None ) :
method_url = r ' editMessageMedia '
2020-07-21 01:20:01 +03:00
media_json , file = convert_input_media ( media )
2018-08-09 19:10:01 +03:00
payload = { ' media ' : media_json }
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 )
2018-08-10 16:47:59 +03:00
return _make_request ( token , method_url , params = payload , files = file , method = ' post ' if file else ' get ' )
2018-08-09 19:10:01 +03:00
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 )
2019-02-23 17:15:20 +03:00
return _make_request ( token , method_url , params = payload , method = ' post ' )
2016-04-14 10:17:53 +03:00
2020-07-21 01:20:01 +03:00
def delete_message ( token , chat_id , message_id , timeout = None ) :
2017-05-07 17:37:03 +03:00
method_url = r ' deleteMessage '
payload = { ' chat_id ' : chat_id , ' message_id ' : message_id }
2020-07-21 01:20:01 +03:00
if timeout :
2021-07-09 10:42:56 +03:00
payload [ ' timeout ' ] = timeout
2019-02-23 17:15:20 +03:00
return _make_request ( token , method_url , params = payload , method = ' post ' )
2017-05-07 17:37:03 +03:00
2016-10-08 15:36:48 +03:00
# Game
2020-05-16 17:34:56 +03:00
def send_game (
token , chat_id , game_short_name ,
2021-06-21 18:39:13 +03:00
disable_notification = None , reply_to_message_id = None , reply_markup = None , timeout = None ,
allow_sending_without_reply = None ) :
2016-10-08 15:36:48 +03:00
method_url = r ' sendGame '
payload = { ' chat_id ' : chat_id , ' game_short_name ' : game_short_name }
2020-05-16 17:34:56 +03:00
if disable_notification is not None :
2016-10-08 15:36:48 +03:00
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 )
2020-05-16 17:34:56 +03:00
if timeout :
2021-07-09 10:42:56 +03:00
payload [ ' timeout ' ] = timeout
2021-06-21 20:59:39 +03:00
if allow_sending_without_reply is not None :
2021-06-21 18:39:13 +03:00
payload [ ' allow_sending_without_reply ' ] = allow_sending_without_reply
2016-10-08 15:36:48 +03:00
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 }
2020-05-16 17:34:56 +03:00
if force is not None :
2016-11-21 09:28:32 +03:00
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
2020-05-16 17:34:56 +03:00
if disable_edit_message is not None :
2016-11-21 09:28:32 +03:00
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)
2020-05-16 17:34:56 +03:00
def send_invoice (
token , chat_id , title , description , invoice_payload , provider_token , currency , prices ,
2021-08-18 23:27:28 +03:00
start_parameter = None , photo_url = None , photo_size = None , photo_width = None , photo_height = None ,
2020-07-21 01:20:01 +03:00
need_name = None , need_phone_number = None , need_email = None , need_shipping_address = None ,
send_phone_number_to_provider = None , send_email_to_provider = None , is_flexible = None ,
2020-05-16 17:34:56 +03:00
disable_notification = None , reply_to_message_id = None , reply_markup = None , provider_data = None ,
2021-07-15 09:27:07 +03:00
timeout = None , allow_sending_without_reply = None , max_tip_amount = None , suggested_tip_amounts = None ) :
2017-05-24 01:23:52 +03:00
"""
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
2020-07-21 01:20:01 +03:00
: param send_phone_number_to_provider : Pass True , if user ' s phone number should be sent to provider
: param send_email_to_provider : Pass True , if user ' s email address should be sent to provider
2017-05-24 01:23:52 +03:00
: 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
2020-07-21 01:20:01 +03:00
: param provider_data : A JSON - serialized data about the invoice , which will be shared with the payment provider . A detailed description of required fields should be provided by the payment provider .
2020-08-21 17:36:08 +03:00
: param timeout :
2021-06-21 18:39:13 +03:00
: param allow_sending_without_reply :
2021-07-15 08:56:04 +03:00
: param max_tip_amount : The maximum accepted amount for tips in the smallest units of the currency
: param suggested_tip_amounts : A JSON - serialized array of suggested amounts of tips in the smallest units of the currency .
At most 4 suggested tip amounts can be specified . The suggested tip amounts must be positive , passed in a strictly increased order and must not exceed max_tip_amount .
2018-08-17 12:49:37 +03:00
: return :
2017-05-24 01:23:52 +03:00
"""
method_url = r ' sendInvoice '
2017-05-25 05:56:58 +03:00
payload = { ' chat_id ' : chat_id , ' title ' : title , ' description ' : description , ' payload ' : invoice_payload ,
2021-08-18 23:27:28 +03:00
' provider_token ' : provider_token , ' currency ' : currency ,
2017-05-25 05:56:58 +03:00
' prices ' : _convert_list_json_serializable ( prices ) }
2021-08-18 23:27:28 +03:00
if start_parameter :
payload [ ' start_parameter ' ] = start_parameter
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
2020-05-16 17:34:56 +03:00
if need_name is not None :
2017-05-24 01:23:52 +03:00
payload [ ' need_name ' ] = need_name
2020-05-16 17:34:56 +03:00
if need_phone_number is not None :
2017-05-24 01:23:52 +03:00
payload [ ' need_phone_number ' ] = need_phone_number
2020-05-16 17:34:56 +03:00
if need_email is not None :
2017-05-24 01:23:52 +03:00
payload [ ' need_email ' ] = need_email
2020-05-16 17:34:56 +03:00
if need_shipping_address is not None :
2017-05-24 01:23:52 +03:00
payload [ ' need_shipping_address ' ] = need_shipping_address
2020-07-21 01:20:01 +03:00
if send_phone_number_to_provider is not None :
payload [ ' send_phone_number_to_provider ' ] = send_phone_number_to_provider
if send_email_to_provider is not None :
payload [ ' send_email_to_provider ' ] = send_email_to_provider
2020-05-16 17:34:56 +03:00
if is_flexible is not None :
2017-05-24 01:23:52 +03:00
payload [ ' is_flexible ' ] = is_flexible
2020-05-16 17:34:56 +03:00
if disable_notification is not None :
2017-05-24 01:23:52 +03:00
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-11-29 08:53:39 +03:00
if provider_data :
payload [ ' provider_data ' ] = provider_data
2020-05-16 17:34:56 +03:00
if timeout :
2021-07-09 10:42:56 +03:00
payload [ ' timeout ' ] = timeout
2021-06-21 20:59:39 +03:00
if allow_sending_without_reply is not None :
2021-06-21 18:39:13 +03:00
payload [ ' allow_sending_without_reply ' ] = allow_sending_without_reply
2021-07-15 08:56:04 +03:00
if max_tip_amount is not None :
payload [ ' max_tip_amount ' ] = max_tip_amount
if suggested_tip_amounts is not None :
payload [ ' suggested_tip_amounts ' ] = json . dumps ( suggested_tip_amounts )
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.
2019-02-23 17:15:20 +03:00
: return :
2017-05-24 01:23:52 +03:00
"""
method_url = ' answerShippingQuery '
payload = { ' shipping_query_id ' : shipping_query_id , ' ok ' : ok }
if shipping_options :
2017-11-13 05:14:10 +03:00
payload [ ' shipping_options ' ] = _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 .
2019-02-23 17:15:20 +03:00
: return :
2017-05-24 01:23:52 +03:00
"""
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
2020-05-16 17:34:56 +03:00
if show_alert is not None :
2016-04-14 09:48:26 +03:00
payload [ ' show_alert ' ] = show_alert
2016-10-08 16:55:28 +03:00
if url :
payload [ ' url ' ] = url
2018-04-26 04:53:55 +03:00
if cache_time is not None :
2016-11-21 09:19:59 +03:00
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 ) }
2018-04-26 04:53:55 +03:00
if cache_time is not None :
2016-01-05 09:07:47 +03:00
payload [ ' cache_time ' ] = cache_time
2020-05-16 17:34:56 +03:00
if is_personal is not None :
2016-01-05 09:07:47 +03:00
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-08-06 09:25:25 +03:00
def get_sticker_set ( token , name ) :
method_url = ' getStickerSet '
return _make_request ( token , method_url , params = { ' name ' : name } )
def upload_sticker_file ( token , user_id , png_sticker ) :
method_url = ' uploadStickerFile '
payload = { ' user_id ' : user_id }
2017-08-06 10:35:43 +03:00
files = { ' png_sticker ' : png_sticker }
2017-08-06 09:25:25 +03:00
return _make_request ( token , method_url , params = payload , files = files , method = ' post ' )
2020-05-16 17:34:56 +03:00
def create_new_sticker_set (
2021-06-22 16:57:34 +03:00
token , user_id , name , title , emojis , png_sticker , tgs_sticker ,
contains_masks = None , mask_position = None ) :
2017-08-06 09:25:25 +03:00
method_url = ' createNewStickerSet '
payload = { ' user_id ' : user_id , ' name ' : name , ' title ' : title , ' emojis ' : emojis }
2021-06-22 16:57:34 +03:00
stype = ' png_sticker ' if png_sticker else ' tgs_sticker '
sticker = png_sticker or tgs_sticker
2017-08-06 10:22:23 +03:00
files = None
2021-06-21 20:59:39 +03:00
if not util . is_string ( sticker ) :
files = { stype : sticker }
2017-08-06 09:25:25 +03:00
else :
2021-06-21 20:59:39 +03:00
payload [ stype ] = sticker
2020-05-16 17:34:56 +03:00
if contains_masks is not None :
2017-08-06 09:25:25 +03:00
payload [ ' contains_masks ' ] = contains_masks
if mask_position :
payload [ ' mask_position ' ] = mask_position . to_json ( )
return _make_request ( token , method_url , params = payload , files = files , method = ' post ' )
2021-06-22 16:57:34 +03:00
def add_sticker_to_set ( token , user_id , name , emojis , png_sticker , tgs_sticker , mask_position ) :
2017-08-06 09:25:25 +03:00
method_url = ' addStickerToSet '
payload = { ' user_id ' : user_id , ' name ' : name , ' emojis ' : emojis }
2021-06-22 16:57:34 +03:00
stype = ' png_sticker ' if png_sticker else ' tgs_sticker '
sticker = png_sticker or tgs_sticker
2017-08-06 10:22:23 +03:00
files = None
2021-06-21 20:59:39 +03:00
if not util . is_string ( sticker ) :
files = { stype : sticker }
2017-08-06 09:25:25 +03:00
else :
2021-06-21 20:59:39 +03:00
payload [ stype ] = sticker
2017-08-06 09:25:25 +03:00
if mask_position :
payload [ ' mask_position ' ] = mask_position . to_json ( )
return _make_request ( token , method_url , params = payload , files = files , method = ' post ' )
def set_sticker_position_in_set ( token , sticker , position ) :
method_url = ' setStickerPositionInSet '
payload = { ' sticker ' : sticker , ' position ' : position }
return _make_request ( token , method_url , params = payload , method = ' post ' )
def delete_sticker_from_set ( token , sticker ) :
method_url = ' deleteStickerFromSet '
payload = { ' sticker ' : sticker }
return _make_request ( token , method_url , params = payload , method = ' post ' )
2021-07-09 10:42:56 +03:00
# noinspection PyShadowingBuiltins
2020-05-02 13:09:52 +03:00
def send_poll (
token , chat_id ,
question , options ,
is_anonymous = None , type = None , allows_multiple_answers = None , correct_option_id = None ,
explanation = None , explanation_parse_mode = None , open_period = None , close_date = None , is_closed = None ,
2021-08-18 19:36:48 +03:00
disable_notification = False , reply_to_message_id = None , allow_sending_without_reply = None ,
2021-06-21 18:39:13 +03:00
reply_markup = None , timeout = None , explanation_entities = None ) :
2019-06-06 21:47:08 +03:00
method_url = r ' sendPoll '
2020-04-25 22:22:08 +03:00
payload = {
' chat_id ' : str ( chat_id ) ,
2020-05-02 13:09:52 +03:00
' question ' : question ,
2021-05-12 00:26:33 +03:00
' options ' : json . dumps ( _convert_poll_options ( options ) ) }
2020-05-02 13:09:52 +03:00
if is_anonymous is not None :
payload [ ' is_anonymous ' ] = is_anonymous
if type is not None :
payload [ ' type ' ] = type
if allows_multiple_answers is not None :
payload [ ' allows_multiple_answers ' ] = allows_multiple_answers
if correct_option_id is not None :
payload [ ' correct_option_id ' ] = correct_option_id
if explanation is not None :
payload [ ' explanation ' ] = explanation
2020-04-25 22:22:08 +03:00
if explanation_parse_mode is not None :
payload [ ' explanation_parse_mode ' ] = explanation_parse_mode
2020-05-02 13:09:52 +03:00
if open_period is not None :
payload [ ' open_period ' ] = open_period
if close_date is not None :
2021-01-16 23:50:25 +03:00
if isinstance ( close_date , datetime ) :
2021-01-14 15:45:47 +03:00
payload [ ' close_date ' ] = close_date . timestamp ( )
else :
payload [ ' close_date ' ] = close_date
2020-05-02 13:09:52 +03:00
if is_closed is not None :
payload [ ' is_closed ' ] = is_closed
2020-04-25 22:22:08 +03:00
2021-08-18 19:36:48 +03:00
if disable_notification :
payload [ ' disable_notification ' ] = disable_notification
2020-04-25 22:22:08 +03:00
if reply_to_message_id is not None :
2019-06-06 21:47:08 +03:00
payload [ ' reply_to_message_id ' ] = reply_to_message_id
2021-06-21 18:39:13 +03:00
if allow_sending_without_reply is not None :
payload [ ' allow_sending_without_reply ' ] = allow_sending_without_reply
2020-04-25 22:22:08 +03:00
if reply_markup is not None :
2019-06-06 21:47:08 +03:00
payload [ ' reply_markup ' ] = _convert_markup ( reply_markup )
2020-05-16 17:34:56 +03:00
if timeout :
2021-07-09 10:42:56 +03:00
payload [ ' timeout ' ] = timeout
2021-06-21 18:39:13 +03:00
if explanation_entities :
payload [ ' explanation_entities ' ] = json . dumps (
types . MessageEntity . to_list_of_dicts ( explanation_entities ) )
2019-06-06 21:47:08 +03:00
return _make_request ( token , method_url , params = payload )
def stop_poll ( token , chat_id , message_id , reply_markup = None ) :
method_url = r ' stopPoll '
payload = { ' chat_id ' : str ( chat_id ) , ' message_id ' : message_id }
if reply_markup :
payload [ ' reply_markup ' ] = _convert_markup ( reply_markup )
return _make_request ( token , method_url , params = payload )
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
2021-01-12 10:47:53 +03:00
def _convert_entites ( entites ) :
2021-01-19 01:27:39 +03:00
if entites is None :
return None
elif len ( entites ) == 0 :
return [ ]
elif isinstance ( entites [ 0 ] , types . JsonSerializable ) :
2021-01-12 10:47:53 +03:00
return [ entity . to_json ( ) for entity in entites ]
2021-01-19 01:27:39 +03:00
else :
return entites
2021-01-12 10:47:53 +03:00
2021-05-12 00:26:33 +03:00
def _convert_poll_options ( poll_options ) :
if poll_options is None :
return None
elif len ( poll_options ) == 0 :
return [ ]
elif isinstance ( poll_options [ 0 ] , str ) :
# Compatibility mode with previous bug when only list of string was accepted as poll_options
return poll_options
2021-05-15 20:08:51 +03:00
elif isinstance ( poll_options [ 0 ] , types . PollOption ) :
2021-05-12 00:26:33 +03:00
return [ option . text for option in poll_options ]
else :
return poll_options
2020-07-21 01:20:01 +03:00
def convert_input_media ( media ) :
2018-08-10 16:47:59 +03:00
if isinstance ( media , types . InputMedia ) :
2020-07-21 01:20:01 +03:00
return media . convert_input_media ( )
2018-08-09 19:10:01 +03:00
return None , None
2020-07-21 01:20:01 +03:00
def convert_input_media_array ( array ) :
2018-01-15 16:08:50 +03:00
media = [ ]
files = { }
for input_media in array :
2018-08-10 16:47:59 +03:00
if isinstance ( input_media , types . InputMedia ) :
2020-05-09 00:51:18 +03:00
media_dict = input_media . to_dict ( )
2018-01-15 16:08:50 +03:00
if media_dict [ ' media ' ] . startswith ( ' attach:// ' ) :
key = media_dict [ ' media ' ] . replace ( ' attach:// ' , ' ' )
files [ key ] = input_media . media
media . append ( media_dict )
return json . dumps ( media ) , files
2017-01-30 17:40:18 +03:00
def _no_encode ( func ) :
def wrapper ( key , val ) :
if key == ' filename ' :
2018-04-18 10:00:05 +03:00
return u ' {0} = {1} ' . format ( key , val )
2017-01-30 17:40:18 +03:00
else :
return func ( key , val )
2017-05-25 05:56:58 +03:00
2017-01-30 17:40:18 +03:00
return wrapper
2020-07-31 01:30:03 +03:00
class ApiException ( Exception ) :
2015-07-02 14:43:49 +03:00
"""
2020-07-31 01:10:34 +03:00
This class represents a base 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 ) :
2020-07-31 01:30:03 +03:00
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
2020-07-31 01:10:34 +03:00
2020-07-31 01:30:03 +03:00
class ApiHTTPException ( ApiException ) :
2020-07-31 01:10:34 +03:00
"""
This class represents an Exception thrown when a call to the
Telegram API server returns HTTP code that is not 200.
"""
def __init__ ( self , function_name , result ) :
super ( ApiHTTPException , self ) . __init__ (
" The server returned HTTP {0} {1} . Response body: \n [ {2} ] " \
. format ( result . status_code , result . reason , result . text . encode ( ' utf8 ' ) ) ,
function_name ,
result )
2020-07-31 01:30:03 +03:00
class ApiInvalidJSONException ( ApiException ) :
2020-07-31 01:10:34 +03:00
"""
This class represents an Exception thrown when a call to the
Telegram API server returns invalid json .
"""
def __init__ ( self , function_name , result ) :
super ( ApiInvalidJSONException , self ) . __init__ (
" The server returned an invalid JSON response. Response body: \n [ {0} ] " \
. format ( result . text . encode ( ' utf8 ' ) ) ,
function_name ,
result )
2020-07-31 01:30:03 +03:00
class ApiTelegramException ( ApiException ) :
2020-07-31 01:10:34 +03:00
"""
This class represents an Exception thrown when a Telegram API returns error code .
"""
def __init__ ( self , function_name , result , result_json ) :
super ( ApiTelegramException , self ) . __init__ (
2020-08-21 17:36:08 +03:00
" Error code: {0} . Description: {1} " \
2020-07-31 01:10:34 +03:00
. format ( result_json [ ' error_code ' ] , result_json [ ' description ' ] ) ,
function_name ,
result )
self . result_json = result_json
2020-08-03 04:39:12 +03:00
self . error_code = result_json [ ' error_code ' ]
2020-07-31 01:10:34 +03:00